概述
简单工厂模式使用户可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的,这种设计有利于整个软件体系结构的优化。如果您还不了解简单工厂模式,请看这里。但是,当产品结构变的复杂的时候,简单工厂就变的难以应付,如果增加一种产品,核心工厂类必须改动,使得整个工厂的可扩展性变得很差,对开闭原则支持不够。工厂方法模式克服了这些缺点,它定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。结构图
工厂方法模式的核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,进负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应该被实例化这种细节,这使得工厂方法模式可以用来允许在不修改具体工厂角色的情况下引进新的产品,这一特点使得他具有超过简单工厂模式的优越性。
工厂方法模式中的角色划分
- 抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
- 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
- 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
- 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
代码
抽象产品类:
/**
* 产品抽象接口
*/
/**
* @author LI Yakang
*
*/
public interface ICellphone {
public void call();
}
具体产品类:
/**
* 苹果手机具体产品类
*/
/**
* @author Li Yakang
*
*/
public class IPhone implements ICellphone {
@Override
public void call() {
System.out.println("我是苹果手机!");
}
}
具体产品类:
/**
* 三星手机具体产品类
*/
/**
* @author LI Yakang
*
*/
public class Anycall implements ICellphone {
@Override
public void call() {
System.out.println("我是三星手机!");
}
}
抽象工厂类:
/**
* 抽象工厂接口
*/
/**
* @author LI Yakang
*
*/
public interface IFactory {
public <T extends ICellphone> T produce(Class<T> c);
}
具体工厂类:
public class PhoneFactory implements IFactory {
@Override
public <T extends ICellphone> T produce(Class<T> c) {
ICellphone cp = null;
try{
cp = (ICellphone)Class.forName(c.getName()).newInstance();
}catch(Exception e){
System.out.println("创建对象错误!");
}
return (T)cp;
}
}
测试类:
/**
* 客户端
*/
/**
* @author LI Yakang
*
*/
public class Client {
public static void main(String[] args) {
IFactory factory = new PhoneFactory();
//生产苹果手机
ICellphone iphone = factory.produce(IPhone.class);
iphone.call();
//生产三星手机
ICellphone anycall = factory.produce(Anycall.class);
anycall.call();
}
}