工厂模式之3种实现方式

(一) 工厂模式概述

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


(二) 简单工厂模式

简单工厂模式: 定义一个创建对象的工厂类, 由工厂类决定创建出哪一种对象的实例, 工厂类内部已封装创建出哪一种对象的实例的逻辑代码

Phone 手机接口

interface Phone {
	// 运行手机的抽象方法
    void run();
}

IPhone 苹果手机实现类

class IPhone implements Phone{
    @Override
    public void run() {
        System.out.println("运行苹果手机");
    }
}

HuaweiPhone 华为手机实现类

class HuaweiPhone implements Phone {
    @Override
    public void run() {
        System.out.println("运行华为手机");
    }
}

PhoneFactory 定义一个创建Phone对象实例的手机工厂类, 内部已封装创建出哪一种品牌手机实例的逻辑代码

class PhoneFactory {

    public Phone createPhone(String phoneType) {
        Phone phone = null;
        if ("IPhone".equals(phoneType)) {
            phone = new IPhone();
        } else if ("HuaweiPhone".equals(phoneType)) {
            phone = new HuaweiPhone();
        }
        return phone;
    }
}

测试

public class SimpleFactory {
    public static void main(String[] args) {
    	// 创建手机工厂类
        PhoneFactory phoneFactory = new PhoneFactory();
		
		// 通过手机工厂类创建 IPhone手机实例对象       
        Phone IPhone = phoneFactory.createPhone("IPhone");
        IPhone.run(); // 运行苹果手机

		// 通过手机工厂类创建 HuaweiPhone手机实例对象   
        Phone HuaweiPhone = phoneFactory.createPhone("HuaweiPhone");
        HuaweiPhone.run(); // 运行华为手机
    }
}

简单工厂模式: 是使用工厂类来创建不同实例的对象, 可以将创建对象的方法静态化, 代码更简洁明了

public class PhoneFactory {

    public static Phone createPhone(String phoneType) {
        Phone phone = null;
        if ("IPhone".equals(phoneType)) {
            phone = new IPhone();
        } else if ("HuaweiPhone".equals(phoneType)) {
            phone = new HuaweiPhone();
        }
        return phone;
    }
}

// 可以直接通过 PhoneFactory.createPhone("phoneType") 创建手机对象

简单工厂模式存在问题

  • 工厂类集中了所有实例(品牌手机)的创建逻辑,一旦这个工厂类不能正常工作,整个系统都会受到影响
  • 违背了开闭原则(对扩展是开放的, 对修改时关闭的), 一旦添加新对象实例(新品牌手机)就不得不修改工厂类的逻辑

(三) 工厂方法模式

工厂方法模式: 先定义一个工厂父类 (负责定义创建对象的抽象接口). 再定义一个工厂子类 (负责生成具体的对象), 工厂方法模式将对象的实例化推迟到工厂子类

在这里插入图片描述

Phone 手机抽象类、IPhone 苹果手机实现类 和 HuaweiPhone 华为手机实现类

/**
 * Phone 手机抽象类: 提供运行手机的抽象方法
 */
abstract class Phone {
    abstract void run();
}

/**
 * IPhone 运行苹果手机
 */
class IPhone extends Phone{
    @Override
    public void run() {
        System.out.println("运行苹果手机");
    }
}

/**
 * HuaweiPhone 运行华为手机
 */
class HuaweiPhone extends Phone {
    @Override
    public void run() {
        System.out.println("运行华为手机");
    }
}

先定义一个工厂抽象父类: 提供创建手机对象的抽象方法

abstract class PhoneFactory {
    abstract Phone createPhone();
}

再定义一个苹果工厂子类: 负责创建具体的对象(苹果手机对象)
再定义一个华为工厂子类: 负责创建具体的对象(华为手机对象)

class IPhoneFactory extends PhoneFactory {

    @Override
    public IPhone createPhone() {
        return new IPhone();
    }
}

class HuaweiPhoneFactory extends PhoneFactory {

    @Override
    public HuaweiPhone createPhone() {
        return new HuaweiPhone();
    }
}

测试:

public class FactoryMethod {
    public static void main(String[] args) {
        // 苹果子类工厂 创建 苹果手机对象
        IPhoneFactory iPhoneFactory = new IPhoneFactory();
        IPhone iPhone = iPhoneFactory.createPhone();
        iPhone.run(); // 运行苹果手机

        // 华为子类工厂 创建 华为手机对象
        HuaweiPhoneFactory huaweiPhoneFactory = new HuaweiPhoneFactory();
        HuaweiPhone huaweiPhone = huaweiPhoneFactory.createPhone();
        huaweiPhone.run(); // 运行华为手机
    }
}

工厂方法模式存在问题: 对象父类 与 对象工厂父类 一一对应, 对象子类 与 对象工厂子类 一一对应. 即: 一个具体工厂子类只能创建一类产品


(四) 抽象工厂模式

抽象工厂模式: Abstarct Factory Pattern, 是围绕一个超级工厂创建其他工厂, 该超级工厂又称为其他工厂的工厂.

在抽象工厂模式中, 超级工厂中提供多个接口, 每个接口负责创建一个相关对象的其他工厂, 工厂创建的对象 不需要显式指定它们的类, 指向抽象类

在抽象工厂模式中, 超级工厂子类负责创建具体的对象: 一个具体超级工厂子类创建多类产品

在这里插入图片描述

/**
 * 电子产品超级工厂: 超级工厂创建其他工厂
 *  创建手机工厂的抽象方法
 *  创建电脑工厂的抽象方法
 */
abstract class ElectronicProductsFactory {

    /**
     * 手机工厂 创建Phone手机抽象对象
     * @return
     */
    abstract Phone createPhoneFactory();

    /**
     * 电脑工厂 创建Computer电脑抽象对象
     * @return
     */
    abstract Computer createComputerFactory();
}

在抽象工厂模式中, 超级工厂子类负责创建具体的对象: 一个具体超级工厂子类创建多类产品

/**
 * 苹果超级工厂子类: 创建苹果手机和苹果电脑对象
 */
class AppleFactory extends ElectronicProductsFactory {

    @Override
    IPhone createPhoneFactory() {
        return new IPhone();
    }

    @Override
    AppleComputer createComputerFactory() {
        return new AppleComputer();
    }
}

/**
 * 华为超级工厂子类: 创建华为手机和华为电脑对象
 */
class HuaweiFactory extends ElectronicProductsFactory {

    @Override
    HuaweiPhone createPhoneFactory() {
        return new HuaweiPhone();
    }

    @Override
    HuaweiComputer createComputerFactory() {
        return new HuaweiComputer();
    }
}

定义 产品抽象类 和 产品实体类

/**
 * 电子产品抽象族类
 */
abstract class ElectronicProducts {

    abstract void run();
}

/**
 * 手机电子产品抽象类
 */
abstract class Phone extends ElectronicProducts {

    @Override
    abstract void run();
}

/**
 * 电脑电子产品抽象类
 */
abstract class Computer extends ElectronicProducts {

    @Override
    abstract void run();
}

/**
 * IPhone 苹果手机实体类
 */
class IPhone extends Phone{

    @Override
    public void run() {
        System.out.println("运行苹果手机");
    }
}

/**
 * HuaweiPhone 华为手机实体类
 */
class HuaweiPhone extends Phone {

    @Override
    public void run() {
        System.out.println("运行华为手机");
    }
}

/**
 * AppleComputer 苹果电脑实体类
 */
class AppleComputer extends Computer {

    @Override
    public void run() {
        System.out.println("运行苹果电脑");
    }
}

/**
 * HuaweiComputer 华为电脑实体类
 */
class HuaweiComputer extends Computer {

    @Override
    public void run() {
        System.out.println("运行华为电脑");
    }
}

抽象工厂模式的优缺点:

  • 将具体产品对象的实例化 推迟到 超级工厂子类实现
  • 超级工厂子类可以创建多个具体产品对象
  • 新增具体产品类时, 只需要增加 具体产品类 和 具体超级工厂子类. 对于新的具体产品类符合开-闭原则
  • 抽象工厂模式 对于新增 抽象产品类, 是需要修改源代码. 因此 抽象工厂模式 对于新的抽象产品类不符合开-闭原则

(五) 总结

工厂模式的意义: 将实例化对象的代码提取处理, 放到一个类中统一管理和维护, 达到和主项目的依赖关系的解耦, 从而提提高项目的扩展和维护性.

工厂模式的依赖抽象原则:

  • 创建对象实例时, 不要直接new对象, 而是把这个new类的动作放在一个工厂的方法中, 并返回. 甚至是, 变量不要直接持有具体类的引用
  • 不要让类继承具体的类, 而是继承抽象类 或者是 接口
  • 不要覆盖类中已经实现的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值