今天看啥  ›  专栏  ›  JackDaddy

解密-工厂模式

JackDaddy  · 简书  ·  · 2020-09-06 18:28

前言

相信每一个开发者每天都会 new 一些对象,当项目规模较小时,这显然是无伤大雅的,但随着项目的扩张,如果仍然这样 "散养式" 创建对象显然是不科学的,不但会造成资源浪费,同时也不利用管理,对项目未来的拓展也是不利的。在这种情况下生产对象的方式是这样的:

public class MyClass {

    public static void main(String[] args) {

        MiPhone miPhone = new MiPhone();

        NokiaPhone nokiaPhone = new NokiaPhone();

        ApplePhone applePhone = new ApplePhone();
    }
}

当项目逐渐膨胀时仍然通过这种方式生产对象的话,项目就会显得较为臃肿,且不利于项目管理,这个时候就可以使用——工厂模式来解决这一难题。

什么是工厂模式

所谓工厂模式指的就是系统性创建同种维度或多种维度对象而衍生出来的一种设计模式,其中有几种不同的分类。

工厂模式分类

工厂模式有几种不同的分类,分别是:

  • 简单工厂模式
  • 方法工厂模式
  • 抽象工厂模式

简单工厂模式

所谓简单模式就是对生产对象的方式进行一个简单封装:

  1. 首先对封装一个接口,在这个接口里去做每个实现类不同的生产方式:
public interface Phone {
    void make();
}
  1. 定义我们生产的对象类同时实现:
//nokia phone
public class NokiaPhone implements Phone{

    public NokiaPhone() {
        this.make();
    }

    @Override
    public void make() {
        System.out.println("this is Nokia Phone ~");
    }
}
--------------------------------------------------------------
//MiPhone
public class MiPhone implements Phone{

    public MiPhone() {
        this.make();
    }

    @Override
    public void make() {
        System.out.println("this is xiao Mi ~");
    }
}
--------------------------------------------------------------
//ApplePhone
public class ApplePhone implements Phone{

    public ApplePhone() {
        this.make();
    }

    @Override
    public void make() {
        System.out.println("this is ApplePhone ~");
    }
}
  1. 定义一个工厂类,通过工厂类生产不同类型的对象:
public class PhoneFactory {

    public static final String MI_TYPE = "Mi";
    public static final String APPLE_TYPE = "Apple";
    public static final String NOKIA_TYPE = "Nokia";

    public Phone makePhoneEasy(String phoneType) {
        if (phoneType.equalsIgnoreCase(MI_TYPE)) {
            return new MiPhone();
        } else if (phoneType.equalsIgnoreCase(APPLE_TYPE)) {
            return new ApplePhone();
        } else if (phoneType.equalsIgnoreCase(NOKIA_TYPE)) {
            return new NokiaPhone();
        }
        return null;
    }
}

以后当想要生产对象时就通过这个工厂去生产不同的对象:

public static void main(String[] args) {
        PhoneFactory easyFactory = new PhoneFactory();
        //造小米
        Phone MiPhone = easyFactory.makePhoneEasy("mi");
        //造苹果
        Phone ApplePhone = easyFactory.makePhoneEasy("apple");
        //造诺基亚
        Phone NokiaPhone = easyFactory.makePhoneEasy("nokia");
    }

同时对于简单生产模式,还有一种静态方法的生产方式,相对来说更加直观一点,在工厂类中进行稍加修改:

public class PhoneFactory {
    /**
     * 生产Mi
     */
    public static Phone makeMiPhone(){
        return new MiPhone();
    }

    /**
     * 生产Apple
     */
    public static Phone makeApplePhone(){
        return new MiPhone();
    }

    /**
     * 生产Nokia
     */
    public static Phone makeNokiaPhone(){
        return new MiPhone();
    }
}

这样生产对象的方式就变成直接类调用了:

public static void main(String[] args) {
        //造小米
        Phone MiPhone = PhoneFactory.makeMiPhone();
        //造苹果
        Phone ApplePhone = PhoneFactory.makeApplePhone();
        //造诺基亚
        Phone NokiaPhone = PhoneFactory.makeNokiaPhone();
    }

通过类名调用的方式会更加直观,且无需进行多次判断。
简单工厂模式

方法工厂模式

无论是通过判断,还是通过静态方法的方式,当新增新的对象类型时都需要修改工厂类,这显然是不符合 开闭原则 的,优雅的做法应该在不修改原来的情况下新增。因此就有了工厂方法模式。

这种方法模式指的是在不修改原有工厂类的前提下通过共产类生产同一维度下的不同对象,通过上面的例子可以理解为当需要生产新的品类的手机时,除了新增新的对象类,同时需要修改工厂类。那么方法模式要解决的就是 修改工厂类的问题

具体步骤为:

  1. 将上面的简单工厂的接口再抽一个接口出来,成为抽象一个工厂接口:
public interface AbstractFactory {
    Phone makePhone();
}
  1. 定义不同品类的对象工厂
//小米工厂
public class MiFactory implements AbstractFactory{

    @Override
    public Phone makePhone() {
        return new MiPhone();
    }
}
-------------------------------------------------------------------
//苹果工厂
public class AppleFactory implements AbstractFactory{

    @Override
    public Phone makePhone() {
        return new ApplePhone();
    }
}
--------------------------------------------------------------------
//诺基亚工厂
public class NokiaFactory implements AbstractFactory {

    @Override
    public Phone makePhone() {
        return new NokiaPhone();
    }
}

通过这种模式生产对象就变成一下这种方式了:

public static void main(String[] args) {
        AbstractFactory miFactory = new MiFactory();
        AbstractFactory appleFactory = new AppleFactory();
        AbstractFactory nokiaFactory = new NokiaFactory();

        miFactory.makePhone();
        appleFactory.makePhone();
        nokiaFactory.makePhone();

        //通过工厂方法模式进行生产,如果要生产新的品类的话只需新增一个生产工厂,而对于抽象工厂无需改动,
        //这显然是符合开闭原则
    }

在这种方式下,如果要生产新的品类对象的话只需新增新的对象类以及对象工厂即可,而不不需要修改原始工厂类
方法工厂模式

抽象工厂模式

方法工厂模式解决了需要修改原始工厂的问题,而抽象工厂要解决的则是品类维度问题,上面例子介绍的是生产手机,而如果此时要生产的是电脑怎么办呢,只需在抽象工厂接口里新增一个生产电脑的方法即可。

  1. 新增生产品类对象接口
public interface Comp {
    void makeComputer();
}
  1. 新增具体生产品类对象
public class AppComputer implements Comp{

    public AppComputer() {
        this.makeComputer();
    }

    @Override
    public void makeComputer() {
        System.out.println("this is Apple Computer");
    }
}

3.新增生产品类对象

public class AppComputer implements Comp{

    public AppComputer() {
        this.makeComputer();
    }

    @Override
    public void makeComputer() {
        System.out.println("this is Apple Computer");
    }
}
  1. 在具体的生产工厂中新增需要实现生产的接口
public class AppleFactory implements AbstractFactory {

    @Override
    public Phone makePhone() {
        return new ApplePhone();
    }

    @Override
    public Comp makeComp() {
        return new AppComputer();
    }
}
  1. 在使用方面的话只需调用新增的方法即可
public static void main(String[] args) {
        AbstractFactory appleFactory = new AppleFactory();

        appleFactory.makePhone();
        appleFactory.makeCoumputer();
    }

从抽象工厂模式可以看出,抽象方法是生产多个对象的一种设计模式,而从方法模式来说,它属于一种特殊的抽象工厂模式,因为他只生产了一种对象。
抽象工厂



原文地址:访问原文地址
快照地址: 访问文章快照