简单工厂模式
原文链接:
http://tianweili.github.com/blog/2015/03/08/simple-factory-pattern/
介绍
简单工厂模式属于创建型模式,又叫做静态工厂方法(static factory method)。但是它并没有归为23种GOF设计模式其中。
简单工厂模式是由工厂对象来决定创建哪一种产品类的实例。
简单说就是工厂对象根据传入的参数,动态的决定创建哪一种产品类的实例,而这些产品类继承自一个父类或一个接口。
UML类图
简单工厂模式的一个基本的UML类图如下所示:
{% img /simple-factory-patternsimple-factory-uml.png %}
在这个UML类图中包含以下角色:
工厂(Factory)
这是简单工厂模式的核心,由它来负责实现创建所有实例的逻辑。工厂对象用来被外界调用,根据传入的参数来决定创建哪一个产品对象。
抽象产品(Abstract Product)
抽象类或接口。是所有具体产品对象的父类,由它来定义所有具体产品的公共接口。
具体产品(Concrete Product)
具体产品是简单工厂模式的创建目标,所有创建的对象都是某个具体产品类的实例。
代码示例
public interface Product {
public void function();
}
public class ProductA implements Product{
@Override
public void function() {
System.out.println("ProductA function ...");
}
}
public class ProductB implements Product{
@Override
public void function() {
System.out.println("ProductB function ...");
}
}
public class Factory {
public Product create(String productName) {
if (productName == null || "".equals(productName)) {
return null;
}
if ("productA".equals(productName)) {
return new ProductA();
} else if ("productB".equals(productName)) {
return new ProductB();
}
return null;
}
}
public class Main {
public static void main(String[] args) {
Factory factory = new Factory();
Product product1 = factory.create("productA");
Product product2 = factory.create("productB");
product1.function();
product2.function();
}
}
输出结果:
ProductA function ...
ProductB function ...
优点
客户类和工厂类分开。消费者任何时候需要某种产品,只需向工厂请求即可。消费者无须修改就可以接纳新产品。
外界不用关注对象创建逻辑,产品对象具体的创建过程由工厂来实现。外界直接给定信息来决定创建哪个产品对象。
明确了各自的职责,有利于整个软件体系结构的优化。
缺点
违反高内聚责任分配原则,将所有的创建逻辑都集中在了工厂类身上。
如果需要添加新的产品类,则需要修改工厂类。
当产品类不断增多,工厂类对产品类型的判断条件过多交织在了一起,会造成逻辑过于复杂,对系统的扩展和维护不利。
使用场景
工厂类创建的产品对象比较少。
外界只需要传入工厂类参数来获得产品对象,对于产品对象的创建过程不关心。
简单工厂模式很容易违反高内聚责任分配原则,所以只是在一些很简单的情况下使用。
应用实例
附件的解压
在工作中,有一个项目模块中要求的功能是:登录邮箱,获取邮件,然后抓取邮件中的附件,下载下来,如果是压缩包,则进行解压,然后进行相应处理。在解压时就用到了简单工厂模式。附件压缩包格式不一,有zip,rar等格式,则把每一种格式的解压和处理都放到一个产品对象中,然后使用一个工厂类来决定创建哪一个产品进行相应的处理。
由于这个压缩包解压方式并不多,判断逻辑并不太复杂,所以也没必要用工厂方法模式,增加代码复杂度。
作者:李天炜
原文链接:http://tianweili.github.com/blog/2015/03/08/simple-factory-pattern/
转载请注明作者和文章出处,谢谢。