美文网首页
设计模式之工厂模式

设计模式之工厂模式

作者: shmilylyp | 来源:发表于2020-12-01 00:10 被阅读0次

    title: 设计模式之工厂模式
    date: 2020-11-26 22:37:00
    tags: java GOF 设计模式


    ​ 在现实生活中我们都知道,原始社会自给自足(没有工厂)、农耕社会有了小作坊(简单工厂),工业革命后有了流水线工厂(工厂方法),现在产业链中有代工厂(抽象工厂)。我们项目的代码也是这样一步一步的迭代过来的。

    一、简单工厂模式

    简单工厂模式是指由一个工厂对象决定创建哪一种产品类的实例,但它不属于Gof的23种设计模式中的其中一种。简单工厂模式适合工厂类创建的对象较少的场景。根据传入的参数来创建对象,至于如何创建就不要关心了。我们还是通过蛋糕来举例。看一下代码

    public interface ICake {
        void makeCake();
    }
    
    public class CakeFactory {
    
        public ICake makeCake(String name) {
            if ("apple".equals(name)) {
                return new AppleCake();
            } else if ("strawberry".equals(name)) {
                return new StrawberryCake();
            } else {
                return null;
            }
        }
    }
    
    public class AppleCake implements ICake{
    
        @Override
        public void makeCake() {
            System.out.println("制作苹果味的蛋糕");
        }
    }
    
    public class StrawberryCake implements ICake{
        @Override
        public void makeCake() {
            System.out.println("制作草莓味的蛋糕");
        }
    }
    

    以上就是一个简单的工厂模式了。但是呢,如果我们多弄几种蛋糕的话,就需要在去改CakeFactory类了。这无疑是很麻烦的。因此,我们可以优化一下,使用动态代理来进行创建实体类。优化代码如下

    public class CakeFactory {
        public ICake makeCake(Class<? extends ICake> clazz) {
            try {
                if (null != clazz) {
                    return clazz.newInstance();
                }
            } catch (Exception e){
                e.printStackTrace();
            }
            return null;
        }
    
        public static void main(String[] args) {
            CakeFactory cakeFactory = new CakeFactory();
            ICake appleCake = cakeFactory.makeCake(AppleCake.class);
            appleCake.makeCake();
            // 输出结果:制作苹果味的蛋糕
        }
    }
    

    这样子的话,我们就可以随便的添加蛋糕,而不需要去修改工厂类喽。我们可以发现简单工厂也是很实用的。

    二、工厂模式

    工厂方法模式是指定义一个创建对象的接口,但是让这个接口的实现类去绝对实例化哪个类,让类的实例化推迟到子类中进行,这样就只需要关心产品所需要的工厂,无需关系细节。就例如报社把订单交到印刷厂里,由每个不同的车间进行操作,印刷,裁纸,装订等不同的车间干不同的活,甚至是不同的小工厂,然而这不是报社需要操心的事。为了习惯,我还是按苹果味的蛋糕和草莓味的蛋糕来举例好吧。我们看如下代码:

    public interface ICakeFactory {
        ICake makeCake();
    }
    
    public class AppleCakeFactory implements ICakeFactory{
        @Override
        public ICake makeCake() {
            return new AppleCake();
        }
    }
    
    public class StrawberryCakeFactory implements ICakeFactory{
        @Override
        public ICake makeCake() {
            return new StrawberryCake();
        }
    }
    

    工厂方法模式适用于一下场景

    - **创建对象需呀大量重复的代码**
    - **客户端不依赖于产品类实例如何呗创建、如何实现等细节**
    - **一个类通过其子类来指定创建哪个对象**
    

    但也很明显哈,它也有一些缺点:

    - **类的个数容易太多,增加复杂度**
    - **增加了系统的抽象性和理解难度**
    

    三、抽象工厂模式

    ​ 抽象工厂呢,他是一个抽象的东西,为什么这么说呢,因为他的名字中有抽象两个字,哈哈。冷不冷。抽象工厂,我的理解呢就是世界上有那么多的蛋糕店,每个蛋糕店都做不一样品种的蛋糕,我们首先去选择哪个蛋糕店,然后在选择这个店里的那个蛋糕。好像有点绕吼。我们还是通过代码来进行理解吧。假如我们有Naomi蛋糕店和木子蛋糕店这两个店,这两个店都属于shmilylyp的,哈哈。每个店里面都卖奶油蛋糕,无糖蛋糕和馒头糕点等。看如下代码:

    public interface IAppleCake {
        void makeAppleCake();
    }
    
    public interface IStrawberryCake {
        void makeStrawberryCake();
    }
    
    public interface ICakeFactory {
        IAppleCake makeAppleCake();
        IStrawberryCake makeStrawberryCake();
    }
    
    public class MuziStoreMakeAppleCake implements IAppleCake{
        @Override
        public void makeAppleCake() {
            System.out.println("木子制作苹果蛋糕工厂");
        }
    }
    
    public class MuziStoreMakeStrawberryCake implements IStrawberryCake{
    
        @Override
        public void makeStrawberryCake() {
            System.out.println("木子制作草莓蛋糕工厂");
        }
    }
    
    public class NaomiStoreMakeAppleCake implements IAppleCake{
        @Override
        public void makeAppleCake() {
            System.out.println("naomi制作苹果蛋糕工厂");
        }
    }
    
    
    public class NaomiStoreMakeStrawberryCake implements IStrawberryCake{
    
        @Override
        public void makeStrawberryCake() {
            System.out.println("naomi制作草莓蛋糕工厂");
        }
    }
    
    public class MuziStoreFactory implements ICakeFactory{
        @Override
        public IAppleCake makeAppleCake() {
            return new MuziStoreMakeAppleCake();
        }
    
        @Override
        public IStrawberryCake makeStrawberryCake() {
            return new MuziStoreMakeStrawberryCake();
        }
    }
    
    public class NaomiStoreFactory implements ICakeFactory{
        @Override
        public IAppleCake makeAppleCake() {
            return new NaomiStoreMakeAppleCake();
        }
    
        @Override
        public IStrawberryCake makeStrawberryCake() {
            return new NaomiStoreMakeStrawberryCake();
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            NaomiStoreFactory naomiStoreFactory = new NaomiStoreFactory();
            naomiStoreFactory.makeAppleCake().makeAppleCake();
            naomiStoreFactory.makeStrawberryCake().makeStrawberryCake();
    
            MuziStoreFactory muziStoreFactory = new MuziStoreFactory();
            muziStoreFactory.makeAppleCake().makeAppleCake();
            muziStoreFactory.makeStrawberryCake().makeStrawberryCake();
        }
    }
    

    很显然,抽象工厂会增加系统的抽象性和理解难度。同时也规定了有可能被创建的产品的集合,导致产品中扩展新的产品困难,需要修改抽象接口。


    ​ 在实际应用中,我们不能放强迫症,做那种纸上谈兵的事。需要根据实际业务情况,选择合适的设计模式。

    相关文章

      网友评论

          本文标题:设计模式之工厂模式

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