GOF23(group of four)
一、设计模式知识
面向对象设计原则
1.开闭原则
2.里氏替换原则
3.依赖倒置原则
4.单一职责原则
5.接口隔离原则
6.迪米特法则
开闭原则优点:
- 对软件测试的影响
软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。 - 可以提高代码的可复用性
粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。 - 可以提高软件的可维护性
遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。
二、设计模式分类
1.创建型的设计模式:
简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式
2.结构型设计模式:
装饰者模式(Decorator) 代理模式(Proxy) 组合模式(Composite) 桥连接模式(Bridge) 适配器模式(Adapter) 蝇量模式(Flyweight) 外观模式(Facade)
3.行为设计模式:
策略模式(Strategy) 、状态模式(State) 、责任链模式(Chain of Responsibility) 、解释器模式(Interpreter) 、命令模式(Command) 、观察者模式(Observer) 、备忘录模式(Memento) 、迭代器模式(Iterator) 、模板方法模式(Template Method) 、访问者模式(Visitor) 、中介者模式(Mediator)
三、实战
1.单例模式
5种
(1)饿汉式
优点:线程安全,调用效率高
缺点:不支持懒加载,类加载时初始化
public class Singleton {
private static final Singleton ourInstance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return ourInstance;
}
}
(2)懒汉式:
优点:支持懒加载
缺点:调用效率低(加锁导致,每次调用都有判断锁是否释放)
public class Singleton {
private static Singleton ourInstance;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (null == ourInstance){
ourInstance = new Singleton();
}
return ourInstance;
}
}
(3)静态内部类
优点:支持懒加载、线程安全、调用效率高
缺点:
public class Singleton {
public static class SingletonInner{
private static SingletonInner ourInstance = new SingletonInner();
public static SingletonInner getInstance() {
return ourInstance;
}
private SingletonInner() {
}
}
}
(4)双重锁:
优点:支持懒加载
缺点:(加锁导致,只有第一次调用需要判断锁是否释放)
public class Singleton {
private static volatile Singleton ourInstance;
private Singleton() {
}
public static Singleton getInstance() {
if (null == ourInstance){
synchronized (Singleton.class){
if (null == ourInstance){
ourInstance = new Singleton();
}
}
}
return ourInstance;
}
}
说明:需要volatile 修饰 ourInstance成员变量
原因:ourInstance=new Singleton();这句话创建了一个对象,他可以分解成为如下3行代码:
1、memory = allocate(); // 1.分配对象的内存空间
2、ctorInstance(memory); // 2.初始化对象
3、ourInstance= memory; // 3.设置sInstance指向刚分配的内存地址
上述伪代码中的2和3之间可能会发生重排序,重排序后的执行顺序如下:
1、memory = allocate(); // 1.分配对象的内存空间
2、ourInstance= memory; // 2.设置sInstance指向刚分配的内存地址,此时对象还没有被初始化
3、ctorInstance(memory); // 3.初始化对象
主要是会有两种情况:一种是先指向分配的地址再初始化对象,另一种是先初始化对象,再指向分配的内存地址。
用volatile关键字指定为后者。
(5)枚举:
优点:线程安全、不能通过反射、反序列修改
缺点:不支持懒加载
public enum Singleton {
ourInstance;
}
1.简单工厂模式
优点:简单,符合单一职责原则
缺点:不符合OCP 开闭原则,增加类的时候需要修改工厂类代码
public class AnimalFactory {
private AnimalFactory(){
}
public static Dog creatDog(){
return new Dog();
}
public static Cat creatCat(){
return new Cat();
}
}
2.工厂方法模式
优点:符合OCP 开闭原则
缺点:增加代码
调用:
Animal animal1 = new DogFactory().creat();
Animal animal2 = new CatFactory().creat();