《Head First》读书笔记
设计原则
一、多用组合,少用继承
eg.基类鸭子,子类有多种鸭子,不同鸭子的行为可能不同也有可能相同
将这种可能出现不同的行为,抽成接口,而不是放到直接基类里,让每个子类实现
上述就是简单的策略模式
二、开放-关闭原则
拓展功能ok,少修改老的功能(影响原来的使用,上游)
例子见装饰者模式
三、依赖倒置原则
依赖抽象,不依赖具体类,将具体类、功能抽象到高层
工厂模式的例子
四、最少知识原则
减少对象之间的交互,只留最重要的几个 。
这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中一部分,会影响到其他部分。如果许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,它需要花许多成本维护,也会因为太复杂而不容易被其他人了解。
尽量不调用对象的子对象的方法,减少耦合和间接依赖的类认知
比如错误的实践 public void fun(){return A.fun2().fun3(); }应该改成,在A里去包掉 fun2() 和 fun3()的逻辑 public void fun(){return A.fun4(); }
设计模式
策略模式
观察者模式
主题对象更新时,通知观察者对象。
通知方实现接口三个方法:注册观察者、删除观察者、通知观察者
观察者实现接口一个方法:update()
Java内置的观察者策略
通知方的类,需要继承Observable,因为setChanged是protect权限
然后每次notify前使用setChanged方法,因为通知前会看 changed标
观察者实现update接口
推拉结合获取通知方的信息,推用的多
内置的缺陷:
1,Observable是一个类而不是一个接口,导致想实现Observable类里方法,无法使用其他类方法时,因为没法多继承
2,setChanged()方法权限是protected,通知方必须继承Observable
装饰者模式
模式说明:装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
场景示例:要造一杯咖啡,加牛奶、加糖等等,需要计算最后价格。现在有咖啡类、牛奶类、糖类
场景2,自己写个输入流装饰器,将大写字母转成小写
两个装饰器叠加
思考:
为什么装饰者和被装饰者需要基类相同?
因为装饰者可以叠加,可以互相装饰,且装饰者可以替代被装饰者,如上图中的ConcreteDecoratorA和ConcreteDecoratorB
构造设计模式关键点:
基类相同
工厂模式
关键:创建对象,可能有些前置动作,初始化某些字段等,把这些实例化的细节,放到【工厂对象】里去做
简单工厂
负责对象的实例化,细节处理,朴实无华
这样每次需要新对象时,就在工厂对象里调用创建方法,而不用关心创建的细节了.
抽象工厂模式
和工厂模式是两种模式
右边有很多产品族,每种产品族实现自己的接口,然后工厂里加上创建每种产品族实例的方法
单件模式
核心思想:构造器私有
第一个关键,解决【正确判断单例是否被创建,不为null】的问题
public class Singleton{private volatile static Singleton uniqueInstance;private Singleton(){}public getInstance(){if(uniqueInstance == null){synchronized(Singleton.class){if(uniqueInstance == null){uniqueInstance = new Singleton();}}}return uniqueInstance;} }
命令模式
核心:解耦动作请求者 和 动作执行者
我发现我已经用过了,launchCheckHandler就是用的这个设计模式。上线检查时,每个检查点的handler都要实现检查方法。
这里就简单跳过了
适配器模式
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
public class 适配器 {private 被适配者;// 实现被适配者的方法void fun(){}... }
外观模式
简化提供的接口
比如原来做一件事要提供很多接口,外观模式 就是简化提供的接口,将复杂的功能自己封装了下
模板方法模式
模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
定义的模板类基类
加钩子方法