二、工厂模式和抽象工厂模式

工厂模式

工厂模式(Factory Pattern)是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

介绍

意图:

定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
主要解决:接口选择问题。

应用实例:
  1. 客户需要购买一辆汽车,只需要到相应的4S店购买即可,而不用去管这辆汽车是怎样生产出来的;
  2. Hibernate换数据库只需要换方言和驱动就可以;
  3. springboot修改web服务器,只需要修改配置参数即可。
优点:
  1. 一个调用者想创建一个对象,只要知道其名称就可以了;
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以;
  3. 屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

使用场景:
  1. 日志记录器:不同的日志级别可能要记录在不同的路径。
  2. 数据库访问,当用户不知道请求最后要访问到哪个数据库时。
  3. 设计一个连接服务器的框架,需要支持三种协议,“POP3”、“IMAP”、“HTTP”,可以把三个协议作为产品类,共同实现一个接口。
注意事项:

作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂农事,就需要引入一个工厂类,会增加系统的复杂度。

实现

比如我们现在要创建一个几何图形,已知可以创建circle、rectangle、square三种图形,以下是具体实现。
FactoryPatternDemo类使用ShapeFactory来获取Shape对象。它将向ShapeFactory传递信息(circle、rectangle、square),以便获取它所需对象的类型。
在这里插入图片描述

工厂模式demo

以生产手机为例

  1. 创建手机接口
public interface Phone {
    /**
     * 打电话
     */
    void call();
}
  1. 创建接口实现类
public class Huawei implements Phone {

    @Override
    public void call() {
        System.out.println("用华为手机打电话!!!");
    }
}
public class OPPO implements Phone{
    @Override
    public void call() {
        System.out.println("用OPPO手机打电话!!!");
    }
}
public class VIVO implements Phone{
    @Override
    public void call() {
        System.out.println("用VIVO手机打电话!!!");
    }
}
  1. 创建手机工厂
public class PhoneFactory {
    public static final String HUAWEI = "HUAWEI";
    public static final String OPPO = "OPPO";
    public static final String VIVO = "VIVO";

    public Phone createPhone(String phoneType){
        if (phoneType == null || phoneType.length() == 0){
            return null;
        }
        switch (phoneType){
            case HUAWEI:
                return new Huawei();
            case OPPO:
                return new OPPO();
            case VIVO:
                return new VIVO();
            default:
                return null;
        }
    }
}
  1. 创建测试类
public class FactoryPatternDemo {
    public static void main(String[] args) {
        PhoneFactory phoneFactory = new PhoneFactory();
        Phone huawei = phoneFactory.createPhone(PhoneFactory.HUAWEI);
        huawei.call();
        Phone oppo = phoneFactory.createPhone(PhoneFactory.OPPO);
        oppo.call();
        Phone vivo = phoneFactory.createPhone(PhoneFactory.VIVO);
        vivo.call();
    }
}
  1. 测试结果

用华为手机打电话!!!
用OPPO手机打电话!!!
用VIVO手机打电话!!!

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式。

介绍

意图

一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。

主要解决

接口选择问题。

应用实例

去吃肯德基的时候,点套餐的时候有主食和饮料,不同的主食和饮料组合成不同的套餐。那么就需要一个套餐工厂来生产套餐,同时需要主食工厂来生产不同的主食,例如汉堡、米饭等,还需要饮料工厂生产不同饮品,例如可乐、果汁等。

优点

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点

产品族扩展非常困难,要增加一系列的某一产品,既要抽象的Creator里加代码,又要在具体的实现类里加代码。

使用场景
  1. QQ秀换装,按照套装换装;
  2. 生成不同操作系统的程序。
注意事项

产品族难扩展,产品等级易扩展。

实现

现在我们要创建带颜色的几何图形,我们将创建Shape和Color接口和实现这些接口的类。下一步创建抽象工厂类AbstractFactory。接着定义工厂类ShapeFactory和ColorFactory,两个工厂都扩展了AbstractFactory。然后创建一个工厂创造器/生成器类FactoryProducer。
AbstractFactoryPatternDemo类使用FactoryProduce来获取AbstractFactory对象。它将向AbstractFactory传递形状信息Shape(circle/rectangle/square),以获取它所需要的形状对象类型。同时还向AbstractFactory传递颜色信息Color(red/green/blue),以获取它所需的颜色对象类型。
在这里插入图片描述

抽象工厂模式demo

沿用抽象工厂demo中的代码

  1. 创建手机壳接口
public interface PhoneShell {
    void color();
}
  1. 创建手机壳实现类
public class BlackPhoneShell implements PhoneShell{
    @Override
    public void color() {
        System.out.println("黑色手机壳!!!");
    }
}
public class BluePhoneShell implements PhoneShell{
    @Override
    public void color() {
        System.out.println("蓝色手机壳!!!");
    }
}
public class RedPhoneShell implements PhoneShell{
    @Override
    public void color() {
        System.out.println("红色手机壳!!!");
    }
}
  1. 创建抽象工厂
public abstract class AbstractFactory {
    //创建手机
    public abstract Phone createPhone(String phoneType);
    //创建手机壳
    public abstract PhoneShell createPhoneShell(String color);

}
  1. 创建手机工厂
public class PhoneFactory extends AbstractFactory{
    public static final String HUAWEI = "HUAWEI";
    public static final String OPPO = "OPPO";
    public static final String VIVO = "VIVO";

    @Override
    public Phone createPhone(String phoneType) {
        if (phoneType == null || phoneType.length() == 0){
            return null;
        }
        switch (phoneType){
            case HUAWEI:
                return new Huawei();
            case OPPO:
                return new OPPO();
            case VIVO:
                return new VIVO();
            default:
                return null;
        }
    }

    @Override
    public PhoneShell createPhoneShell(String color) {
        return null;
    }
}
  1. 创建手机壳工厂
public class PhoneShellFactory extends AbstractFactory{
    public static final String RED = "RED";
    public static final String BLUE = "BLUE";
    public static final String BLACK = "BLACK";

    @Override
    public Phone createPhone(String phoneType) {
        return null;
    }

    @Override
    public PhoneShell createPhoneShell(String color) {
        if (color == null || color.length() == 0){
            return null;
        }
        switch (color){
            case RED:
                return new RedPhoneShell();
            case BLUE:
                return new BluePhoneShell();
            case BLACK:
                return new BlackPhoneShell();
            default:
                return null;
        }
    }
}
  1. 创建一个工厂创造器
public class FactoryProducer {
    public static final String PHONE = "PHONE";
    public static final String PHONE_SHELL = "PHONESHELL";

    public static AbstractFactory createFactory(String factpryType){
        if (PHONE.equals(factpryType)){
            return new PhoneFactory();
        }else if (PHONE_SHELL.equals(factpryType)){
            return new PhoneShellFactory();
        }
        return null;
    }
}
  1. 创建抽象工厂测试类
public class AbstractFactoryDemo {
    public static void main(String[] args) {
        AbstractFactory phoneFactory = FactoryProducer.createFactory(FactoryProducer.PHONE);
        Phone huawei = phoneFactory.createPhone(PhoneFactory.HUAWEI);
        Phone oppo = phoneFactory.createPhone(PhoneFactory.OPPO);
        Phone vivo = phoneFactory.createPhone(PhoneFactory.VIVO);
        huawei.call();
        oppo.call();
        vivo.call();

        AbstractFactory phoneShellFactory = FactoryProducer.createFactory(FactoryProducer.PHONE_SHELL);
        PhoneShell blackPhoneShell = phoneShellFactory.createPhoneShell(PhoneShellFactory.BLACK);
        PhoneShell bluePhoneShell = phoneShellFactory.createPhoneShell(PhoneShellFactory.BLUE);
        PhoneShell redPhoneShell = phoneShellFactory.createPhoneShell(PhoneShellFactory.RED);
        blackPhoneShell.color();
        bluePhoneShell.color();
        redPhoneShell.color();

    }
}
  1. 测试结果

用华为手机打电话!!!
用OPPO手机打电话!!!
用VIVO手机打电话!!!
黑色手机壳!!!
蓝色手机壳!!!
红色手机壳!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值