6大设计原则
单一职责原则(Single Responsibility Principle,SRP)
里氏替换原则(Liskov Substitution Principle,LSP)
- 定义:所有引用基类的地方必须能透明地使用其子类的对象
依赖倒置原则(Dependence Inversion Principle,DIP)
- 定义:
- 高层模块不应该依赖低层模块,两者都应该依赖其抽象;
- 抽象(抽象类)不应该依赖细节(实现类);
- 细节应该依赖抽象。
接口隔离原则
- 定义:建立单一接口,不要建立臃肿庞大的接口(接口尽量细化,同时接口中的方法尽量少)
迪米特法则(Law of Demeter,LoD)
- 定义:一个对象应该对其他对象有最少的了解(弱耦合)
开闭原则
- 是六大原则中最基础的
- 定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。(一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化)
23种设计模式
单例模式(Singleton Pattern)
- 定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
- 优点:
- 减少内存开支
- 减少系统的性能开销
- 可以避免对资源的多重占用
- 单例模式可以在系统设置全局的访问点,优化和共享资源访问
- 缺点:
- 单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现
- 单例模式与单一职责原则有冲突
- 使用场景:
- 在一个系统中,要求一个类有且仅有一个对象,如果出现多个对象就会出现“不良反应”,可以采用单例模式
- 代码实现:
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return singleton;
}
public static void doSomething(){
}
}
# 线程不安全
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
# 线程安全
public class Singleton {
private static Singleton singleton = null;
private Singleton(){
}
public static synchronized Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
工厂方法模式
- 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
- 优点:
- 良好的封装性,代码结构清晰
- 扩展性优秀
- 屏蔽产品类(产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化)
- 是典型的解耦框架
- 使用场景:
- 工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考虑是否要增加一个工厂类进行管理,增加代码的复杂度;
- 需要灵活的、可扩展的框架时,可以考虑采用工厂方法模式;
- 可以用在异构项目(不同语言的项目)中;
- 扩展
- 静态工厂模式(简单工厂模式)
- 多个工厂类
- 替代单例模式
- 延迟初始化
抽象工厂模式
- 定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
- 优点:
- 缺点:
- 使用场景
- 一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式
- 注意事项
- 在抽象工厂模式的缺点中,我们提到抽象工厂模式的产品族扩展比较困难,但是一定要清楚,是产品族扩展困难,而不是产品等级。在该模式下,产品等级是非常容易扩展的,增加一个产品等级,只要增加一个工厂类负责新增加出来的产品生产任务即可。也就是说横向扩展容易,纵向扩展困难。
模版方法模式
- 定义:定义一个操作中的算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
- 构成:
- 基本方法:基本方法也叫做基本操作,是由子类实现的方法,并且在模板方法被调用
- 模版方法:可以有一个或几个,一般是一个具体方法,也就是一个框架,实现对基本方法的调度,完成固定的逻辑
- 优点:
- 封装不变部分,扩展可变部分
- 提取公共部分代码,便于维护
- 行为由父类控制,子类实现
- 缺点:抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响
- 使用场景:
- 多个子类有公有的方法,并且逻辑基本相同时
- 重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现
- 重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见“模板方法模式的扩展”)约束其行为
- 扩展
- 添加钩子函数:有了钩子方法模板方法模式才算完美,大家可以想想,由子类的一个方法返回值决定公共部分的执行结果,是不是很有吸引力呀!
建造者模式(生成器模式)
- 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
- 通用类图:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e76fff602918d86aedd203669fc66043.png)
- 角色构成
- Product产品类:通常是实现了模板方法模式,也就是有模板方法和基本方法,这个参考第10章的模板方法模式。例子中的BenzModel和BMWModel就属于产品类。
- Builder抽象建造者:规范产品的组建,一般是由子类实现。例子中的CarBuilder就属于抽象建造者。
- ConcreteBuilder具体建造者:实现抽象类定义的所有方法,并且返回一个组建好的对象。例子中的BenzBuilder和BMWBuilder就属于具体建造者。
- Director导演类:负责安排已有模块的顺序,然后告诉Builder开始建造,在上面的例子中就是我们的老大,××公司找到老大,说我要这个或那个类型的车辆模型,然后老大就把命令传递给我,我和我的团队就开始拼命地建造,于是一个项目建设完毕了。
代理模式
原型模式
中介者模式
命令模式
责任链模式
装饰模式
策略模式
适配器模式
迭代器模式
组合模式
观察者模式
门面模式
备忘录模式
访问者模式
状态模式
状态模式
解释器模式
享元模式
桥梁模式