创建和使用分离——简单工厂

作者: RunAlgorithm | 来源:发表于2019-05-13 22:41 被阅读0次

    1. 定义

    简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

    工厂模式的作用,将实例的创建和使用进行分离,将实例化的配置和创建的过程封装在工厂类中。

    简单工厂模式是工厂三兄弟之一,但并不属于 GOF 的 23 种设计模式。

    使用的时候,无需关心实例化细节,只要传递自己想要的产品类型,创建过程委托给工厂来实现。

    2. 设计

    主要元素:

    • 抽象产品。声明产品的属性和行为。
    • 具体产品。抽象产品的实现。
    • 具体工厂。负责产品的创建。

    类图如下:

    简单工厂模式-类图

    2.1. 普通简单工厂

    一个工厂类,一个工厂方法,对传入的类型进行枚举,实例化产品。

    public class NormalSimpleFactory {
    
        public static final String TYPE_CHINESE = "Chinese";
        public static final String TYPE_ENGLISH = "English";
        public static final String TYPE_GERMAN = "German";
    
        public IProduct getProduct(String type) {
            if (TYPE_CHINESE.equals(type)) {
                return new ChineseProduct();
            } else if (TYPE_ENGLISH.equals(type)) {
                return new EnglishProduct();
            } else if (TYPE_GERMAN.equals(type)) {
                return new GermanProduct();
            } else {
                return null;
            }
        }
    }
    

    虽然还是有 if else 对类型进行判断,但对于之前零散于各处的创建代码来说已经得到了很大的优化。

    2.2. 多方法简单工厂

    一个工厂类,多个工厂方法,无需枚举,每种方法返回对应的实例。

    public class MultiMethodFactory {
    
        public IProduct getChineseProduct() {
            return new ChineseProduct();
        }
    
        public IProduct getEnglishProduct() {
            return new EnglishProduct();
        }
    
        public IProduct getGermanProduct() {
            return new GermanProduct();
        }
    }
    

    可以不用去维护类型类表与类型和实例的关联管理。

    2.3. 静态工厂方法(使用较多)

    无需实例化工厂,调用方法直接为静态,所以也被称为 静态工厂方法

    public class StaticMethodSimpleFactory {
    
        public static IProduct getChineseProduct() {
            return new ChineseProduct();
        }
    
        public static IProduct getEnglishProduct() {
            return new EnglishProduct();
        }
    
        public static IProduct getGermanProduct() {
            return new GermanProduct();
        }
    }
    

    3.应用

    工厂模式用来就创建与使用解耦。工厂三兄弟有不同适用范围。

    一般来说,简单会在几个情况下使用:

    • 需要生产的产品比较简单,数量较少(因为简单工厂把所有产品创建集中起来,多了就复杂了)。
    • 使用者无需记住创建细节,只要告诉工厂需要的类型。

    3.1. JDK:MessageDigest

    进行消息摘要的工具

    MD2

    MessageDigest md=MessageDigest.getInstance("MD2");
    

    MD5

    MessageDigest md=MessageDigest.getInstance("MD5");
    

    SHA

    MessageDigest md = MessageDigest.getInstance("SHA");
    

    3.2. JDK:Executors

    静态工厂方法提供默认的线程池。

    阿里开发手册已经不推荐使用,希望我们自己创建线程池,并约束好最大任务数或最大线程数。

    这里仅仅作为一个举例。

    缓存线程池:�

    ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
    

    固定线程数线程池:

    ExecutorService fixCacheThreadPool = Executors.newFixedThreadPool(10);
    

    单线程线程池:

    ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
    

    定时执行任务线程池:

    ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(4);
    

    4. 特点

    4.1. 优点

    • 易于阅读:因为类型不一样,需要 if else 分支判断,过多的 if else 代码块会造成维护困难,集中在工厂有利于代码复用和可读性。
    • 易于修改:调用者可以遵循依赖倒置原则,面向抽象编程。创建过程交给工厂实现,如果更换产品只需要调整工厂。
    • 易于复用:如果对象创建需要大量复杂的配置和初始化操作,内聚到工厂进行复用。

    4.2. 缺点

    • 要修改工厂。如果要新增产品,还是要修改工厂,不符合开闭原则

      优化思路

      如果产品相当复杂的话,可以考虑改用工厂方法或抽象工厂

    4.3. 注意事项

    • 生成的产品要足够简单,然后业务逻辑不能太复杂。如果创建过程过于复杂的话,可以考虑用其他模式进行配合。

    相关文章

      网友评论

        本文标题:创建和使用分离——简单工厂

        本文链接:https://www.haomeiwen.com/subject/iipdaqtx.html