
一、简单工厂模式
简单工厂模式不是 23 种里的一种,简而言之,就是有一个专门生产某个产品的类。
比如下图中的鼠标工厂,专业生产鼠标,给参数 0,生产戴尔鼠标,给参数 1,生产惠普鼠标。

二、工厂模式
工厂模式也就是鼠标工厂是个父类,有生产鼠标这个接口。
戴尔鼠标工厂,惠普鼠标工厂继承它,可以分别生产戴尔鼠标,惠普鼠标。
生产哪种鼠标不再由参数决定,而是创建鼠标工厂时,由戴尔鼠标工厂创建。
后续直接调用鼠标工厂.生产鼠标()即可

三、抽象工厂模式
抽象工厂模式也就是不仅生产鼠标,同时生产键盘。
也就是 PC 厂商是个父类,有生产鼠标,生产键盘两个接口。
戴尔工厂,惠普工厂继承它,可以分别生产戴尔鼠标+戴尔键盘,和惠普鼠标+惠普键盘。
创建工厂时,由戴尔工厂创建。
后续工厂.生产鼠标()则生产戴尔鼠标,工厂.生产键盘()则生产戴尔键盘。

四、单例模式
- 懒汉式,线程不安全
这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式,线程安全
能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 饿汉式
这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
- 双检锁/双重校验锁
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
- 静态内部类
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
- 枚举
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
5、建造者模式
去肯德基点餐,我们可以认为点餐就属于一个建造订单的过程。我们点餐的顺序是无关的,点什么东西也是没有要求的,可以单点,也可以点套餐,也可以套餐加单点,但是最后一定要点确认来完成订单。
public class OrderBuilder{
private Burger mBurger;
private Suit mSuit;
//单点汉堡,num为数量
public OrderBuilder burger(Burger burger, int num){
mBurger = burger;
}
//点套餐,实际中套餐也可以点多份
public OrderBuilder suit(Suit suit, int num){
mSuit = suit;
}
//完成订单
public Order build(){
Order order = new Order();
order.setBurger(mBurger);
order.setSuit(mSuit);
return order;
}
}
六、原型模式
原型角色:定义用于复制现有实例来生成新实例的方法;
implements Cloneable // 1.(抽象类或者接口)实现 java.lang.Cloneable 接口
public Shape clone(); // 2.定义复制现有实例来生成新实例的方法
具体原型角色:实现用于复制现有实例来生成新实例的方法
public Shape clone() {// 2.实现复制现有实例来生成新实例的方法(也可以由超类完成)
Shape clone = null;
try {
clone = (Shape) clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
使用者角色:维护一个注册表,并提供一个找出正确实例原型的方法。最后,提供一个获取新实例的方法,用来委托复制实例的方法生成新实例。
private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>();//维护一个注册表public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(),circle);
Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(),square);
Rectangle rectangle = new Rectangle();
rectangle.setId("3");
shapeMap.put(rectangle.getId(),rectangle);
}
public static Shape getShape(String shapeId) {//提供一个获取新实例的方法
Shape cachedShape = shapeMap.get(shapeId);//提供一个找出正确实例原型的方法
return (Shape) cachedShape.clone();//委托复制实例的方法生成新实例。
}
网友评论