简单工厂模式
代码实现:github
简单工厂是一种编码的风格以及习惯,不属于GOF23种设计模式之一。主类需要什么告诉工厂即可,工厂会主动生产出主类需要的对象。但是此种方式总是违反开闭原则。
主类依赖于实现类:
方法实现的简单工厂:
也有用static修饰的,但是无法继承
反射实现的简单工厂
数据库就使用的此种方式
工厂方法
代码实现:github
工厂方法:将创建对象的过程延迟到子类进行创建
抽象工厂方法
代码实现:github
此方法新增产品族很方便,但新增产品等级比较麻烦,需要对原有产品等级结构进行修改,会违背开闭原则,所以抽象工厂方法一般适用于产品等级结构相对固定的,并且需要多个产品组合在一起变成一个产品族时使用。
工厂方法模式针对产品等级结构
抽象工厂模式针对产品族
产品等级结构:联想拯救者,戴尔游匣,华硕飞行堡垒(都是笔记本)
产品族:拯救者水杯,拯救者耳机,拯救者机箱(一个品牌不同产品)
单例模式
代码实现:github
单例模式:
单例模式的精髓即将构造函数私有化,让此类无法被别的程序new出来
懒汉式注重延迟加载,只有使用的时候才会new出来,但在多线程场景下会照成前一个线程new出来的对象被后一个线程覆盖,这时我们可以加上synchronized是之变成线程安全的。(synchronized如果加在static上则是锁当前类class,如果不是加在static上则是锁堆内存中的对象)
DoubleCheck实现懒汉式:在一个对象被new出来时,会执行以下过程:
1.分配对象的内存空间。
2.在此空间内初始化对象。
3.设置instance指向内存空间。
但在Java中2和3可能会颠倒,当颠倒时若有别的线程进入执行代码逻辑会有安全问题。所以我们有两种解决方法:不允许2与3颠倒(在instance上加入volatile修饰)或者不允许别的线程介入(静态内部类)。
饿汉式是在类加载的时候就初始化完毕了,使用静态代码块实现比较简单。
序列化与反序列化,反射会破坏单例模式,其中反射可以改变原有类的无参构造函数访问权限或原有类的私有元素。
(JAD反编译工具)
Enum实现单例模式不会受到序列化与反射的破坏,且比较优雅,effective Java推荐使用此种方法实现单例模式。
容器实现单例模式一般在需要很多的单例时使用,可以统一管理这些实例对象,但是线程不安全。
ThreadLocal隔离了多个线程对数据的访问冲突,为每个线程都分配了一个对象,所以在多线程访问时各自不会影响。
建造者模式
代码实现:github
建造者模式更加注重于方法的调用顺序,工厂模式更加注重于创建出产品。建造者模式一般可以创造出比较复杂的产品,因为可以改变方法调用顺序来创照出不同的产品,而工厂模式只关心产品是否被创造出来。