设计模式
一、创建型设计模式
1.工厂模式
定义一个创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类
-
简单工厂只是解决对象创建的问题,类经常改动(见下方策略模式有demo)
-
@判断问题依然存在:利用反射解决
-
工厂模式最终形态-用泛型实现反射类工厂模式
public class OperaFactory { public static <T> T getInstance(String className) { T obj = null; try { obj = (T) Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); } return obj; } }
乘法类
public class OperationMul extends Operation {
@Override
public double GetResult() {
double result=0;
result=numberA*numberB;
return result;
}
}
主类()调用的地方
var oper: Operation? =
OperaFactory.getInstance("com.jiaxufei.calculator.OperationMul")
oper?.numberA = numberA?.toDouble()
oper?.numberB = numberB?.toDouble()
//计算结果
tv_result.text = oper?.GetResult()!!.toBigDecimal().toString()
2.单例模式 -Application
保证一个类只有一个实例,并提供一个访问它的全局访问点
public class BaseApplication
public static BaseApplication INSTANCE;
public static BaseApplication getInstance() {
if (INSTANCE == null) {
synchronized (BaseApplication.class) {
if (INSTANCE == null) {
INSTANCE = new BaseApplication();
}
}
}
return INSTANCE;
}
}
需要注意多线程时候的单例
3.建造者模式(Builder)-AlertDialog.Builder
建造者模式UML类图将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
-
1.定义具体的产品类(Product):电脑
public class Computer { private String mCPU; private String mMemory; private String mHD; public void setCPU(String CPU) { mCPU = CPU; } public void setMemory(String memory) { mMemory = memory; } public void setHD(String HD) { mHD = HD; } }
-
2.定义抽象建造者(Builder):组装电脑的过程
public abstract class Builder { public abstract void buildCPU(String cpu);//组装CPU public abstract void buildMemory(String memory);//组装内存 public abstract void buildHD(String hd);//组装硬盘 public abstract Computer create();//返回组装好的电脑 }
-
3.创建具体的建造者(ConcreteBuilder):装机人员
public class ConcreteBuilder extends Builder { //创建产品实例 private Computer mComputer = new Computer(); @Override public void buildCPU(String cpu) {//组装CPU mComputer.setCPU(cpu); } @Override public void buildMemory(String memory) {//组装内存 mComputer.setMemory(memory); } @Override public void buildHD(String hd) {//组装硬盘 mComputer.setHD(hd); } @Override public Computer create() {//返回组装好的电脑 return mComputer; } }
-
4.定义指挥者类(Director):老板委派任务给装机人员
public class Director { private Builder mBuild = null; public Director(Builder build) { this.mBuild = build; } //指挥装机人员组装电脑 public void Construct(String cpu, String memory, String hd) { mBuild.buildCPU(cpu); mBuild.buildMemory(memory); mBuild.buildHD(hd); } }
-
4.测试方法
public void CreatComputer() { Builder builder = new ConcreteBuilder();//创建建造者实例,(装机人员) Director direcror = new Director(builder);//创建指挥者实例,并分配相应的建造者,(老板分配任务) direcror.Construct("i7-6700", "三星DDR4", "希捷1T");//组装电脑 }
二、结构型设计模式
1.适配器模式(Adapter)
适配器模式UML类图将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原来由于接口不兼容而不同一起工作的那些类可以一起工作。
- Target这是客户所期望的接口,目标可以是抽象类也可以是接口
public interface Target {
public void request();
}
-Adaptee 需要适配的类
public class Adaptee {
public void SpecificRequest(){
Log.i("提示:","特殊请求");
}
}
- Adapter 通过内部包装一个Adaptee对象,把原接口转换成目标接口
public class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
@Override
public void request() {
adaptee.SpecificRequest();
}
}
- 客户端测试
Adapter adapter=new Adapter();
adapter.request();
2.代理模式
代理模式UML类图.png 代码模版.png为其对象提供一种代理以控制对这个对象的访问
- 1.抽象类
public abstract class Subject {
public abstract void Request();
}
- 2.真实实现类
public class RealSubject extends Subject {
@Override
public void Request() {
Log.e("日志","真实的请求");
}
- 3.代理类
public class Proxy extends Subject{
RealSubject realSubject;
@Override
public void Request() {
if (realSubject==null){
realSubject=new RealSubject();
}
realSubject.Request();
}
}
- 4.运行类
fun runProxy() {
var proxy=Proxy()
proxy.Request()
}
3.装饰模式 Decorate
当系统需要新功能时,向旧的类中添加新的代码
优点:把类的核心功能和装饰功能区分开,简化原有的类
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public void show(){
Log.e("装扮的是{0}",name);
}
}
服饰类
public class Finery extends Person {
protected Person component;
//打扮
public void Decorate(Person component) {
this.component = component;
}
@Override
public void show() {
if (component != null) {
component.show();
}
}
}
具体服饰类-大体恤
public class TShirts extends Finery {
@Override
public void show() {
Log.e("日志","大体恤");
super.show();
}
}
具体服饰类-垮裤
public class BigTrouser extends Finery {
@Override
public void show() {
Log.e("日志","垮裤");
super.show();
}
}
主类运行(Kotlin)
fun demoRun() {
//装饰模式
var person = Person("小明")
var short = TShirts()
var kk=BigTrouser()
short.Decorate(person)
kk.Decorate(short)
kk.show()
}
打印日志
2020-04-14 15:10:05.173 15955-15955/? E/日志: 垮裤
2020-04-14 15:10:05.173 15955-15955/? E/日志: 大体恤
2020-04-14 15:10:05.173 15955-15955/? E/日志装扮的是{0}: 小明
三、行为型设计模式
1.策略模式
定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。如:商场促销方式,打折、满减等
public abstract class CashSuper {
public abstract double acceptCash(double money);
}
正常收费子类
public class CashNormal extends CashSuper
{
@Override
public double acceptCash(double money) {
return money;
}
}
打折收费子类
public class CashRebate extends CashSuper {
private double moneyRebate = 1d;
public CashRebate(String moneyRebate) {
this.moneyRebate = Double.parseDouble(moneyRebate);
}
@Override
public double acceptCash(double money) {
return money * moneyRebate;
}
}
返利收费子类
public class CashReturn extends CashSuper {
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(String moneyCondition, String moneyReturn) {
this.moneyCondition = Double.parseDouble(moneyCondition);
this.moneyReturn = Double.parseDouble(moneyReturn);
}
@Override
public double acceptCash(double money) {
double result=money;
if (money >= moneyCondition) {
result = money - Math.floor(money / moneyCondition) * moneyReturn;
}
return result;
}
策略模式类(1)
public class CashContext {
private CashSuper cs;
//根据构造方法,传入具体收费策略
public CashContext(CashSuper cashSuper) {
this.cs = cashSuper;
}
//根据收费模式的不同,获取计算结果
public double GetResult(double money) {
return cs.acceptCash(money);
}
}
现金收费简单工厂类(2)
public class CashFactory {
public static CashSuper createCashAccept(String type) {
CashSuper cs = null;
switch (type) {
case "正常收费":
cs = new CashNormal();
break;
case "打8折":
cs = new CashRebate("0.8");
break;
case "满300返100":
cs = new CashReturn("300", "100");
break;
}
return cs;
}
}
//策略和简单工厂模式相结合(3)
public class CashContextNew {
private CashSuper cs;
//根据构造方法,传入具体收费策略
public CashContextNew(String type) {
switch (type) {
case "正常收费":
cs = new CashNormal();
break;
case "打8折":
cs = new CashRebate("0.8");
break;
case "满300返100":
cs = new CashReturn("300", "100");
break;
}
}
//根据收费模式的不同,获取计算结果
public double GetResult(double money) {
return cs.acceptCash(money);
}
}
主逻辑调用(1)或(2)或(3)即可
2.观察者模式(各种控件的监听)
观察者模式UML类图观察者模式定义了一种一对多的的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
观察者的不足:抽象通知者依赖抽象观察者
弥补不足,最高境界:事件委托
- 创建抽象观察者
public interface Observer {//抽象观察者
public void update(String message);//更新方法
}
- 创建具体观察者
public class Boy implements Observer {
private String name;//名字
public Boy(String name) {
this.name = name;
}
@Override
public void update(String message) {//男孩的具体反应
System.out.println(name + ",收到了信息:" + message+"屁颠颠的去取快递.");
}
}
public class Girl implements Observer {
private String name;//名字
public Girl(String name) {
this.name = name;
}
@Override
public void update(String message) {//女孩的具体反应
System.out.println(name + ",收到了信息:" + message+"让男朋友去取快递~");
}
}
- 创建抽象主题/通知者
public interface Observable {//抽象被观察者
void add(Observer observer);//添加观察者
void remove(Observer observer);//删除观察者
void notify(String message);//通知观察者
}
- 创建具体主题/通知者
public class Postman implements Observable{//快递员
private List<Observer> personList = new ArrayList<Observer>();//保存收件人(观察者)的信息
@Override
public void add(Observer observer) {//添加收件人
personList.add(observer);
}
@Override
public void remove(Observer observer) {//移除收件人
personList.remove(observer);
}
@Override
public void notify(String message) {//逐一通知收件人(观察者)
for (Observer observer : personList) {
observer.update(message);
}
}
}
- 客户端测试
public void test(){
Observable postman=new Postman();
Observer boy1=new Boy("路飞");
Observer boy2=new Boy("乔巴");
Observer girl1=new Girl("娜美");
postman.add(boy1);
postman.add(boy2);
postman.add(girl1);
postman.notify("快递到了,请下楼领取.");
}
- 输出结果
路飞,收到了信息:快递到了,请下楼领取.屁颠颠的去取快递.
乔巴,收到了信息:快递到了,请下楼领取.屁颠颠的去取快递.
娜美,收到了信息:快递到了,请下楼领取.让男朋友去取快递~
今日分享:
任何的需求的变更都是要成本的,高手同样的事情花最小的代价,面对同样的需求,当然是改动越小越好。而面向对象重要点之一就是封装变化点。
网友评论