设计模式之工厂模式


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 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();
    }
}

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


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

你可能感兴趣的:(设计模式之工厂模式)