工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
通用源码
public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
public abstract void method2();
}
public class ConcreteProduct1 extends Product {
public void method2() {
//业务处理
}
}
public class ConcreteProduct2 extends Product {
public void method2() {
//业务处理
}
}
public abstract class Creator {
/*
* 创建一个产品对象,其输入参数类型可以自行设置
* 通常为String,Enum,Class等,当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
Product product=null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
*继续业务处理
*/
}
}
优点:
1. 良好的封装性。
2. 扩展性好。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。
工厂模式的扩展;
1. 简单工厂模式,也叫静态工厂模式。只要把上述代码的抽象工厂类去掉。然后把工厂类的方法改为static即可。
2. 多个工厂类。每个具体的产品实现类对应一个专门生产该产品的工厂类。当然在复杂的应用中一般采用多工厂的方法。然后在增加一个一个协调类,避免调用者与各个子工厂交流,协调类的作用是封装子工厂类,对高层模块提供统一的访问接口。
3. 替代单例模式。通过反射方式创建。
public class Singleton {
//不允许通过new产生一个对象
private Singleton(){
}
public void doSomething(){
//业务处理
}
}
public class SingletonFactory{
private static Singleton singleton;
static{
try{
Class cl = Class.forName(Singleton.class.getName());
//获得无参构造
Constructor constructor = cl.getDeclaredConstructor();
//设置无参构造函数是可访问的。
constructor.setAccessible(true);
singleton = (Singleton)constructor.newInstance();
}catch(Exception e){
//异常处理
}
}
public static Singleton getSingleton{
return singleton;
}
}
4, 延迟初始化。一个对象呗消费完毕后并不立刻释放,工厂类保持其初始状态,等待再次被使用。
public class Factory {
private static final Map<String,Product> prMap = new HashMap();
public static synchronized Product createProduct(String type) throws Exception{
Product product =null;
//如果Map中已经有这个对象
if(prMap.containsKey(type)){
product = prMap.get(type);
}else{
if(type.equals("Product1")){
product = new ConcreteProduct1();
}else{
product = new ConcreteProduct2();
}
//同时把对象放到缓存容器中
prMap.put(type,product);
}
return product;
}
}
抽象工厂模式
定义:为创建一组相关或相互依赖的对象提供一个接口,并且无需指定他们的具体类。
通用类图:
通用源码类图:
通用源码:
//抽象产品类
public abstract class AbstractProductA {
//每个产品类共有的方法
public void shareMethod(){
}
//每个产品类相同方法,不同实现
public abstract void doSomething();
}
public class ProductA1 extends AbstractProductA {
@Override
public void doSomething() {
System.out.println("产品A1的实现方法");
}
}
public class ProductA2 extends AbstractProductA {
@Override
public void doSomething() {
System.out.println("");
}
}
public abstract class AbstractProductB {
public void shareMethod(){
}
public abstract void doSomething();
}
public class ProductB1 extends AbstractProductB {
@Override
public void doSomething() {
System.out.println("");
}
}
public class ProductB2 extends AbstractProductB {
@Override
public void doSomething() {
System.out.println("");
}
}
public abstract class AbstractCreator {
//创建A产品家族
public abstract AbstractProductA createProductA();
//创建B产品家族
public abstract AbstractProductB createProductB();
}
public class Creator1 extends AbstractCreator {
//只生产产品等级为1的A产品
public AbstractProductA createProductA() {
return new ProductA1();
}
//只生产产品等级为1的B产品
public AbstractProductB createProductB() {
return new ProductB1();
}
}
public class Creator2 extends AbstractCreator {
//只生产产品等级为2的A产品
public AbstractProductA createProductA() {
return new ProductA2();
}
//只生产产品等级为2的B产品
public AbstractProductB createProductB() {
return new ProductB2();
}
}
public class Client {
public static void main(String[] args) {
/定义出两个工厂
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
AbstractProductA a1 = creator1.createProductA();
AbstractProductA a2 = creator2.createProductA();
AbstractProductB b1 = creator1.createProductB();
AbstractProductB b2 = creator2.createProductB();
}
}
优点:
1. 封装性好
2. 产品族内的约束为非公开状态。
使用场景:
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如一个文本编辑器和一个图片处理器。但是不同操作系统下他们的代码实现是不同的。此时他们就有了共同的约束即操作系统。我们就可以使用抽象工厂模式产生不同操作系统下的编辑器和图片处理器。
注意事项:
抽象工厂模式产品家族扩展难,但是产品等级扩展容易。