先看看这个模式的发展流程,3个角色:Customer(消费者),Product(产品)和Factory(工厂)。
传统的类创建过程
消费者需要什么产品,自己去创建它。
public class Customer {
public Product CreateProduct() {
return new Product();
}
}
这个方式的缺点就是,代码都在一起,扩展性差。当有多个产品的时候,Customer必须实现每一个产品的Create。严重违反了开闭原则。
工厂模式一: 简单工厂模式
将产品的创建放到工厂中去解决。
/**
* 工厂类
*/
class Factory {
// 可以看到这里的类型返回,还是有点问题的
// 因为不同产品返回的类型是不一样的
// 这里有一种解决方案就是,将所有的产品抽象出一个抽象类出来,然后让各个产品类去继承这个产品抽象类,如下
public static Product CreateProduct(String type) {
// 根据 type 的类型返回对应的产品类
if( type == "type1") {
return (Product) new Product1();
} else if ( type == "type2") {
return (Product) new Product2();
}
}
}
/**
* 产品类
*/
abstract class Product {}
class Product1 extends Product {}
class Product2 extends Product {}
/**
* 客户类
*/
public class Customer {
public static Product GetProduct(String type) {
return Factory::CreateProduct(type);
}
public static void main(String[] args) {
Product1 pro1 = (Product1) GetProduct("type1");
}
}
上面的模式看着比较不错了,下面我们从这3个类来分析下这种模式的开闭性。评价场景:当客户需要新的产品类型的时候,如Product3.
对于Customer,仅仅只需要在 GetProduct 方法中传入Product3的type值就行,如 type3 , 对于 Customer 是很符合开闭原则的
对于Factory, 当增加Product3的创建的时候,我们就需要修改 CreateProduct 中的逻辑了,对 Factory 来说 开闭性 不是很好
对于Product,肯定是要添加新的Product的
class Product3 extends Product {}
可以看到对于 Product,Product1 和 Product2 来说,是没有影响的,符合开闭性。
可见到这里,我们需要将Factory方法再抽象下,以符合开闭性原则。
工厂模式二 : 工厂方法
将 Factory 中的静态方法 CreateProduct ,抽象成一个抽象的方法,然后在各个不同的Product类中去实现。这样 Factory 就成了接口了。
interface Factory {
public abstract Prodcut CreateProduct();
}
class Product1Impl implements Factory {
public Product CreateProduct() {
return (Product) new Product1();
}
}
可以看到,如果这样设计的话,那么Product的类型的选择就交给了Customer了
public class Customer {
public static Product GetProduct(String type) {
Product pro = null;
if(type == "type1") {
Product1Impl pro1Impl = new Product1Impl();
pro = pro1Impl.CreateProduct();
}
return pro;
}
...
}
将Facotry中的方法,通过每个特定产品的实现类去做。这个时候,如果我们增加一个新的产品。我们需要增加如下的内容:
// 新增加产品类型的实现类
class Product3Impl implements Factory {
public Product CreateProduct() {
return (Product) new Product3();
}
}
// 新增加的产品类型类
class Product3 extends Product {}
// 在客户类中需增加的内容
public class Customer {
public static Product GetProduct(String type) {
...
else if( type == "type3") {
Product3Impl pro3Impl = new Product3Impl();
pro = pro3Impl.CreateProduct();
}
}
}
看到对于客户类又有了改动。这个时候其实可以使用反射来做。怎么做?
首先每个类都有 .class 属性,例如上面的代码在包 com 中,则
System.out.println(Product1.class);
// output
class com.Product1
工厂模式三:工厂抽象
未完
对于工厂模式的理解有点问题,等待更新。如果有比较好相关blog,求推荐,看看。