设计模式 的创建型模式 工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
创建型模式
简单工厂模式:
public class SimplePizzaFactory { public Pizza createPizza(String pizzaType){ Pizza pizza = null; if(pizzaType.equals("greek")){ pizza = new GreekPizza(); return pizza; } if(pizzaType.equals("cheese")){ pizza = new CheesePizza(); return pizza; } return null; } }
这样写可以看到一个问题:简单的工厂模式创建类依赖于工程类,如果想要扩展,则必须对工厂类进行修改,违背了开闭原则,所以从设计角度来说,如何解决这个问题?可以定义一个抽象类,并且通过不同的工厂类实现该接口。
public class LDOrderPizza extends AllPizza { @Override public Pizza createPizza(String pizzaType) { Pizza pizza = null; if(pizzaType.equals("greek")){ pizza = new GreekPizza(); return pizza; } if(pizzaType.equals("cheese")){ pizza = new CheesePizza(); return pizza; } return null; } } public class CNOrderPizza extends AllPizza { @Override public Pizza createPizza(String pizzaType) { Pizza pizza = null; if(pizzaType.equals("greek")){ pizza = new GreekPizza(); return pizza; } if(pizzaType.equals("cheese")){ pizza = new CheesePizza(); return pizza; } return null; } }
这样写的好处是什么呢,你现在想实现一个功能,只需要实现一个类就ok了,无需改变已有的代码,扩展性更好。
工厂方法存在的问题则是用户需要取LD工厂订披萨,就必须去LD,想去CN则必须去CN工厂。为了解决这个问题,我们把工厂类抽象为接口。
public class LDOrderPizza extends AllPizza { public LDOrderPizza(String address) { super(address); } @Override public Pizza createPizza(String pizzaType) { Pizza pizza = null; if(pizzaType.equals("greek")){ pizza = new GreekPizza(); return pizza; } if(pizzaType.equals("cheese")){ pizza = new CheesePizza(); return pizza; } return null; } } public interface AbsFactory { Pizza createPizza(String pizzaType) ; }
这样写的好处不需要根据不同的工厂继续创建对应的工厂类,只需要传递指定的工厂名称即可。
适用的场景:大量的产品需要创建,并且有共同的接口。
普通工厂模式:只支持扩展产品。
其中抽象工厂模式,用来生产不同工厂的产品,支持扩展性产品,支持增加产品种类工厂。
单例模式:
分为懒加载和预加载。
懒加载:在使用对象的时候才会加载对象。
预加载:还没是使用的时候就已经创建好放入内存。
很明显,预加载只有一条return语句,线程是安全的的,但是缺点是性能的浪费,但是懒加载在两个线程同时访问的时候,有机会发生线程不安全问题。
public class LanSingleton { private static volatile Singleton singleton = null; private LanSingleton() { } private static synchronized Singleton getInstance() { if(singleton == null){ synchronized (Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton; } } class Singleton { }
上面加了双重效验以及volatile,为了防止创建不同的对象,volatile为了保证可见性,因为两个线程访问的时候,会导致重排序发生。
生成器模式:
封装一个复杂对象构造过程,并允许按步奏构造。
优点就是可以将一个对象分解为各个组件,将组件封装起来,控制整个对象的生成过程。
缺点不同类型的对象要实现不同具体构造器的类,大大增加了类的数量。
与工厂模式不同的是,会按多个步奏来构造对象额,而工厂模式只有一个步奏。
原型模式:
通过复制现有实例来创建新的实例,无需知道相对应类的信息。
原型模式的本质就是clone,可以解决构造复杂对象资源问题,某些场景提升构建对象效率。还提供保护性拷贝,可以通过返回一个拷贝对象的形式,实现只读的限制。