设计模式系列之一:简单工厂模式

1.1 定义

 简单工厂模式属于创建型模式,又称为静态工厂方法模式,在简单工厂模式中,可以根据参数的不同,来返回不同类的实例,简单工厂模式专门定义一个类来负责创建子类的实例,被创建的类通常有一个共同的父类

1.2 简单工厂模式结构图(简版)

                             

 Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象

 IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口

 Product:具体产品类,是简单工厂模式的目标类

1.3 简单工厂的实现一

 假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑了,随着业务的拓展,这个代工生产商还要生产惠普和mac电脑;

 这样我们就需要用一个单独的类来专门生产电脑,这就用到了简单工厂模式,同时用到了继承、封装、多态等面向对象编程的思想,下面我们来实现简单工厂模式

1.3.1 产品抽象类

public abstract class Computer {
    /**
     * 产品的抽象方法,由具体的产品类去实现
     */
    public abstract void start();

}

1.3.2  具体实现类

public class LenovoComputer extends Computer {

    @Override
    public void start() {
        System.out.println("lenovo computer run");
    }
}
public class MacComputer extends Computer {
    @Override
    public void start() {
        System.out.println("Mac computer run");
    }
}
public class HpComputer extends Computer {
    @Override
    public void start() {
        System.out.println("hp computer run");
    }
}

1.3.3  工厂类

public class ComputerFactory {
    public static Computer createComputer(String type) {
        Computer computer = null;
        switch (type) {
            case "lenovo":
                computer = new LenovoComputer();
                break;
            case "hp":
                computer = new HpComputer();
                break;
            case "Mac":
                computer = new MacComputer();
                break;
            default:
                break;
        }
        return computer;
    }
}

1.3.4  UML类图

                          

1.4 优缺点

 优点:

 1. 工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品;实现了对责任的分割,它提供了专门的工厂类用于创建对象

 2. 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。

 3. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

缺点:

 1. 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

 2. 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。

 3. 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,同样破坏了“开闭原则”;在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护

 4. 简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构

1.5 适用场景

 1. 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。

 2. 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数

1.6 模式应用

 1. JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间

public final static DateFormat getDateInstance(); 
public final static DateFormat getDateInstance(int style); 
public final static DateFormat getDateInstance(int style,Locale locale);

 2. 获取不同加密算法的密钥生成器

KeyGenerator keyGen=KeyGenerator.getInstance("DESede");

1.7 开闭原则

 对于上面两种简单工厂模式的实现方法,如果我们要添加新的 parser,那势必要改动到 RuleConfigParserFactory 的代码,那这是不是违反开闭原则呢?

 实际上,如果不是需要频繁地添加新的 parser,只是偶尔修改一下 RuleConfigParserFactory 代码,稍微不符合开闭原则,也是完全可以接受的

 尽管简单工厂模式的代码实现中,有多处 if 分支判断逻辑,违背开闭原则,但权衡扩展性和可读性,这样的代码实现在大多数情况下(比如,不需要频繁地添加 parser,也没有太多的 parser)是没有问题的

原文地址:https://www.cnblogs.com/oxygenG/p/13192040.html