工厂模式

2019/08/27 设计模式 共 3623 字,约 11 分钟

工厂模式

设计模式学习的第二天,工厂模式,在此记录。

简单工厂模式

简单工程模式并不属于Gof23种设计模式,只能算工厂模式的一种实现方法,因为它违背了设计模式六大原则的开放-封闭原则,因为每次添加一个产品类都需要在获取实例的方法中修改代码。
开放-封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。

定义

创建一个工厂类,可以根据传入参数不同获取不同的实例。

适用场景

  1. 需要创建的对象较少
  2. 客户端不关心对象的创建过程

实例

现在创建一个获取手机的工厂,每个手机有一个拍照的功能。

  1. 首先创建手机的公共接口(抽象产品:负责描述所有实例所共有的公共接口)
public interface Phone {

    /**
     * 每只手机都拥有的功能,如拍照
     */
    void takePhotos();
}
  1. 创建两个手机类,实现Phone公共接口(具体产品:简单工厂创建的对象,需要实现抽象产品) ````java public class IPhone implements Phone { @Override public void takePhotos() { System.out.println(“IPhone…魔鬼前置”); } }

public class HuaWei implements Phone { @Override public void takePhotos() { System.out.println(“华为…也能照亮你的美”); } }


3. 创建工厂类,它有一个public方法,可根据传入的手机品牌获得不同的手机实体类(工厂类:简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。)

````java
public class PhoneFactory {

    /**
     * 根据传入的手机品牌获得手机实体类
     * 简单工厂:根据传入不同的参数创建不同的对象
     * @param brand 手机品牌
     * @return Phone
     */
    public static Phone getPhone(String brand) {
        Phone phone = null;
        if (brand.equalsIgnoreCase("huawei")) {
            phone = new HuaWei();
        } else if (brand.equalsIgnoreCase("iphone")) {
            phone = new IPhone();
        }
        return phone;
    }

    public static void main(String[] args) throws Exception {
        Phone phone = getPhone("huawei");
        phone.takePhotos();
    }
}

使用反射机制改善简单工厂,使得简单工厂不违反开闭原则

public class PhoneFactory {

    /**
     * 使用反射解决简单工厂每次增加新手机(产品类)都需要改代码的弊端
     * 使得简单工厂不违反开闭原则
     * @param clazz
     * @return Object
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static Object getPhoneClass(Class<? extends Phone> clazz) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        return Class.forName(clazz.getName()).newInstance();
    }

    public static void main(String[] args) throws Exception {
        // 传入的参数需要import或者类的全路径,可以使用配置文件的方式替代
        IPhone iPhone = (IPhone) getPhoneClass(IPhone.class);
        iPhone.takePhotos();
    }
}
  • 获取产品类方法的入参需要import或者类的全路径,可以使用配置文件的方式替代

工厂方法模式

工厂方法模式是简单工厂模式的升级版,在工厂方法模式中,为不同的对象提供不同的工厂去创建实例。

定义

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

实例

在上一节的手机实例的基础上,增加工厂接口类PhoneFactory,并创建两种品牌的手机工厂类,实现工厂接口。
PhoneFactory抽象工厂:是工厂方法模式的核心,创建对象的工厂类必须实现这个接口。 IPhoneFactory、HuaWeiFactory具体工厂:实现抽象工厂接口的具体工厂类,用来创建某种产品对象。

public interface PhoneFactory {

    /**
     * 获得手机对象的接口方法
     * @return Phone
     */
    Phone getPhone();
}

public class IPhoneFactory implements PhoneFactory {
    @Override
    public Phone getPhone() {
        return new IPhone();
    }
}

public class HuaWeiFactory implements PhoneFactory {
    @Override
    public Phone getPhone() {
        return new HuaWei();
    }
}

抽象工厂模式

抽象工厂模式是工厂方法模式的升级版,在抽象工厂模式中,抽象工厂接口有若干个方法需要具体工厂类实现。换言之,抽象工厂模式中的工厂类可以创建多个对象(着多个对象没有继承、实现接口的关系)

定义

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。(在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于产生多种不同类型的对象)

实例

  1. 创建一个耳机接口,表明这是工厂生产手机的配件。
public interface HeadSet {

    /**
     * 耳机有播放音乐的功能
     */
    void playMusic();
}
  1. 创建IPhoneHuaWei对象分别对应的耳机配件——AirPodsFreeBuds,实现HeadSet耳机接口
public class AirPods implements HeadSet {
    @Override
    public void playMusic() {
        System.out.println("AirPods...好像还挺好用?");
    }
}

public class FreeBuds implements HeadSet {
    @Override
    public void playMusic() {
        System.out.println("华为蓝牙耳机...好像丑一点?");
    }
}
  1. 创建新的工厂接口,包含获得手机和获得耳机两个方法。
public interface NewPhoneFactory {

    /**
     * 获得手机对象的接口方法
     * @return Phone
     */
    Phone getPhone();

    /**
     * 获得耳机的接口方法
     * @return
     */
    HeadSet getHeadSet();
}
  1. 创建两个新的手机工厂类,实现新的工厂接口
public class NewIPhoneFactory implements NewPhoneFactory {
    @Override
    public Phone getPhone() {
        return new IPhone();
    }

    @Override
    public HeadSet getHeadSet() {
        return new AirPods();
    }
}

public class NewHuaWeiFactory implements NewPhoneFactory {
    @Override
    public Phone getPhone() {
        return new HuaWei();
    }

    @Override
    public HeadSet getHeadSet() {
        return new FreeBuds();
    }
}
  1. 测试代码如下
public static void main(String[] args) {
    NewIPhoneFactory iPhoneFactory = new NewIPhoneFactory();
    // 获得手机对象
    Phone iPhone = iPhoneFactory.getPhone();
    iPhone.takePhotos();
    // 获得耳机对象
    HeadSet airPods = iPhoneFactory.getHeadSet();
    airPods.playMusic();
}

工厂方法模式和抽象工厂模式的区别

  • 工厂方法模式中的工厂是生产单一产品的。
  • 抽象工厂模式中的工厂是生产一整套有产品的(至少要生产两个产品),且这些产品必须相互是有关系或有依赖的。

源代码 GitHub地址

版权声明:本文为Planeswalker23所创,转载请带上原文链接,感谢。

文档信息

Search

    Table of Contents