简单工厂模式定义
定义一个工厂类,它可以依据参数的不同返回不同类的实例,被创建的实例具有共同的父类。
简单工厂模式结构图
简单工厂模式角色介绍
Factory:工厂角色,即产品工厂类,负责提供静态工厂方法,依据参数不同,创建并返回不同的产品实例,返回值类型都是抽象产品Product。
Product:抽象产品角色,它是所有产品的父类,也是工厂角色工厂方法的返回值类型。
ConcreteProduct:具体产品角色,它是产品工厂负责创建的目标,所有具体产品角色都继承了抽象产品角色,实现了抽象产品中声明的抽象方法。
简单工厂模式结构代码
抽象产品:
public abstract class Product {
public abstract void sayName();
}
具体产品:
public class ConcreteProductA extends Product {
public void sayName() {
System.out.println("product a");
}
}
public class ConcreteProductB extends Product {
public void sayName() {
System.out.println(" product b");
}
}
简单工厂:
public class Factory {
public static Product createProduct(String type){
if ("ConcreteProductA".equalsIgnoreCase(type)){
return new ConcreteProductA();
}else if ("ConcreteProductB".equalsIgnoreCase(type)){
return new ConcreteProductB();
}else {
return null;
}
}
}
通过泛型和反射机制优化简单工厂类:
public class Factory {
public static <T extends Product> T createProduct(Class<T> type){
Product product = null;
try {
//实例化产品对象
product = (Product)Class.forName(type.getName()).newInstance();
//初始化产品对象
//todo 。。。
}catch (Exception e){
System.out.println("e.getMessage() = " + e.getMessage());
}
return (T)product;
}
}
此处思考:既然工厂方法通过反射机制实例化了对象,客户端能否直接采用反射机制实例化产品,也做到了面向接口编程?
我的解释:因为复杂对象实例化之后还需要很多的初始化工作,客户端既要负责创建产品、又要实例化产品、还要使用产品,有违单一职责原则。
客户端:
public class Client {
public static void main(String[] args) {
//Product product = Factory.createProduct("ConcreteProductB");
//使用优化模式
Product product = Factory.createProduct(ConcreteProductB.class);
product.sayName();
}
}
简单工厂模式运行机制
简单工厂的静态工厂方法通过参数类型不同,判断创建并返回不同的产品实例;
客户端通过调用简单工厂提供的静态工厂方法获取产品实例;
简单工厂模式解决的问题
将随时变化的具体产品类与客户端解耦,避免具体产品替换对客户端修改;避免具体产品类散落在各个客户端,只需在简单工厂类里面进行统一维护即可。
简单工厂模式符合面向对象的设计原则
简单工厂模式符合面向对象依赖倒转原则和里氏替换原则,部分符合开闭原则。
客户端针对抽象产品编程,而不是针对具体产品编程,等程序运行阶段,逻辑执行又由具体产品负责,属于标准的依赖倒转原则和里氏替换原则,并且此时也符合开闭原则;但产品的创建过程集中在简单工厂类静态工厂方法内,具体产品发生变化,需要修改静态工厂方法,此时不符合开闭原则,所以说部分符合开闭原则。