设计模式(五) Factory——工厂模式

工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

一般人们对工厂模式还有详细划分,大致如下:

  1. 简单工厂
  2. 静态工厂
  3. 工厂方法
  4. 抽象工厂

其实按照严格的设计模式来说,只有工厂方法抽象工厂才属于严格意义上的设计模式,其他两项只不过是后来被人们经常提到,所以暂且也归纳到工厂设计模式。

工厂模式分类

目前就先安装上诉的分类对每种工厂模式依次进行讲解。

简单工厂

简单工厂从字面意义上可以看出,该工厂模式是最简单且最容易理解的工厂模式。由于工厂就是用来替代自主new的过程。name简单工厂就仅实现了使用一个工厂来创建并返回对象的功能。
例:现在希望一个用简单工厂的方式来返回不同样式的手机产品

package com.liqk.dp.factory;

/**
 * 简单工厂模式
 * 使用同一个工厂来负责创建某个具体的产品
 */
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        HuaWei hw = new SimpleFactory().createHuaWeiPhone();
        hw.call();
        Mi mi = new SimpleFactory().createMiPhone();
        mi.call();
        IPhone iPhone = new SimpleFactory().createIPhone();
        iPhone.call();
    }
}

//华为手机
class HuaWei { public void call(){ System.out.println("华为手机开始通话");}}

//小米手机
class Mi{ public void call(){ System.out.println("小米手机开始通话"); }}
//苹果手机
class IPhone{public void call(){ System.out.println("苹果手机开始通话"); }}

class SimpleFactory{

    //创建华为手机工厂
    HuaWei createHuaWeiPhone(){
        System.out.println("此处模拟生产过程:create a HuaWei Phone");
        return new HuaWei();
    }

    //创建小米手机工厂
    Mi createMiPhone(){
        System.out.println("此处模拟生产过程:create a Mi Phone");
        return new Mi();
    }

    //创建苹果手机工厂
    IPhone createIPhone(){
        System.out.println("此处模拟生产过程:create a IPhone");
        return new IPhone();
    }

}

输出结果:

此处模拟生产过程:create a HuaWei Phone
华为手机开始通话
此处模拟生产过程:create a Mi Phone
小米手机开始通话
此处模拟生产过程:create a IPhone
苹果手机开始通话

以上就是简单工厂模式,当然还可以简单改建,例如在工厂内部根据传入不同的参数来调用响应的工厂来生产产品。但此只是为了讲解简单工厂,所以不再过多优化。
使用简单工厂,可以理解为就是使用一个同一个工厂,然后再该工厂内部划分出不同生产线,每条生产线可以生成响应的产品。
优点
使用简单工厂,可以将生成之前的前置内容进行定义,也就是控制生成流程,在此项目中就是System.out.println("此处模拟生产过程:create a xxx");这行代码,可以在创建之前执行其前置任务。这样每次只要调用该工厂方法即可完成整个生产过程。
缺点
扩展性很差,如果该工厂添加一条新的生产线,例如要再生产Vivo手机,则需要改动器工厂类内部的内容,实现Vivo的生产方法。不符合“开闭”原则。

静态工厂

静态工厂,顾名思义就是通过静态方法创建出来的工厂。典型的案例就是单例模式。所以此处不再过多说明。

工厂方法 (FactoryMethod)

工厂方法,真正的工厂模式之一。其主旨为:
定义一个工厂的接口/抽象类,让其实现类/子类自己决定实例化哪一个工厂类,工厂方法使其创建过程延迟到实现类/子类进行。
废话不多说,直接上代码。仍然是造手机的例子。

package com.liqk.dp.factory.mf;

/**
 * 方法工厂
 * 也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品
 * 将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了
 */
public class FactoryMethodDemo {
    public static void main(String[] args) {
        PhoneFactory huaweimf = new HuaWeiFactory();
        PhoneFactory mimf = new MiFactory();
        PhoneFactory iphonemf = new IPhoneFactory();
        huaweimf.make().call();
        mimf.make().call();
        iphonemf.make().call();

    }
}
//定义电话接口,方便扩展
interface Phone{void call();}

//定义华为手机 实现Phone接口
class HuaWei implements Phone{
    @Override
    public void call() {
        System.out.println("华为手机开始通话");
    }
}

//定义小米手机 实现Phone接口
class MI implements Phone{
    @Override
    public void call() {
        System.out.println("小米手机开始通话");
    }
}

//定义苹果手机 实现Phone接口
class IPhone implements Phone{
    @Override
    public void call() {
        System.out.println("苹果手机开始通话");
    }
}

/*
 * 定义方法接口 只声明常见方法 不实现具体生成方式
 * 谁实现  谁重写 提高扩展性
 */
interface PhoneFactory{
    Phone make();
}

//创建华为工厂 实现抽象工厂  专门负责生产华为手机
class HuaWeiFactory implements  PhoneFactory{

    @Override
    public Phone make() {
        System.out.println("生前前置内容:Start Create HUAWEI");
        return new HuaWei();
    }
}

//创建小米工厂 实现抽象工厂  专门负责生产小米手机
class MiFactory implements  PhoneFactory{

    @Override
    public Phone make() {
        System.out.println("生前前置内容:Start Create MI Phone");
        return new MI();
    }
}

//创建苹果工厂 实现抽象工厂  专门负责生产苹果手机
class IPhoneFactory implements  PhoneFactory{

    @Override
    public Phone make() {
        System.out.println("生前前置内容:Start Create IPhone");
        return new IPhone();
    }
}

运行结果:

生前前置内容:Start Create HUAWEI
华为手机开始通话
生前前置内容:Start Create MI Phone
小米手机开始通话
生前前置内容:Start Create IPhone
苹果手机开始通话

以上即是工厂方法模式
优点
当每添加一条新的手机生产线时,并不需要修改总工厂(简单模式中的统一工厂)中的代码,只需要创建一个子生成线并继承/实现工厂接口中的生产接口并具体实现即可。这样符合“开闭”原则,大大的提高了产品的扩展性。
缺点
这总模式只能针对单一产品,即要做手机就只能做手机的生产线(PhoneFactory)。如果想添加新的产品(例如PC),则又要开辟一个新的产品接口(PCFactory),并创建该工厂的具体实现类及实现过程。这样不方便品牌管理,例如华为需要两个工厂才分别创建手机和PC的产品。

抽象工厂 (Abstract Factory)

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

即抽象出一个总工厂,在工厂中并不生产具体的产品,而是定义相关产品族的接口。之后由具体的工厂实现抽象工厂,并实现相关产品族的生产过程。

说明:在此处要提出一个概念,叫产品族。指的是某个品牌或类型的一系列相关产品。例如:小米有手机和PC,华为也有手机和PC,苹果亦然。那么这里的手机和PC就被称之为产品族。

例如现在除了手机,还需要生产PC。每个品牌都有这两个产品的实现方式。代码实现:

package com.liqk.dp.factory.abstractfactory;

/**
 * 抽象工厂
 * 创建工厂的工厂
 * 封装一个抽象工厂,其内部生产很多产品,但都不具体实现,而是声明其产品的实现接口
 * 那个品牌或类型需要生产,则自定义具体的工厂实现该抽象工厂,并实现其内部产品族的具体实现
 */
public class AbstractFactoryDemo {

    public static void main(String[] args) {
        //小米工厂-生成相关Phone和PC
        AbstractFactory mi = new MiFactory();
        mi.createPhone().call();
        mi.createPC().play();
        //华为工厂-生成相关Phone和PC
        AbstractFactory hw = new HuaWeiFactory();
        hw.createPhone().call();
        hw.createPC().play();
        //苹果工厂-生成相关Phone和PC
        AbstractFactory ap = new AppleFactory();
        ap.createPhone().call();
        ap.createPC().play();
    }
}
//手机接口
interface Phone{    void call();}
//相关手机产品类
class MiPhone implements Phone{public void call(){System.out.println("小米正在通话");}}
class HuaWeiPhone implements Phone{public void call(){System.out.println("华为正在通话");}}
class IPhone implements Phone{public void call(){System.out.println("苹果正在通话");}}

//PC接口
interface PC{   void play();}
//相关PC产品类
class MiPC implements PC{public void play(){System.out.println("小米PC正在打字");}}
class HuaWeiPC implements PC{public void play(){System.out.println("华为PC正在打字");}}
class MacBook implements PC{public void play(){System.out.println("MacBook正在打字");}}


//定义抽象工厂--核心
interface AbstractFactory{
    //声明需要生产产品的实现接口
    Phone createPhone();
    PC createPC();
}
//小米工厂--可以生成小米手机和小米PC
class MiFactory implements AbstractFactory{

    @Override
    public Phone createPhone() {
        return new MiPhone();
    }

    @Override
    public PC createPC() {
        return new MiPC();
    }
}

//华为工厂--可以生成华为手机和华为PC
class HuaWeiFactory implements AbstractFactory{

    @Override
    public Phone createPhone() {
        return new HuaWeiPhone();
    }

    @Override
    public PC createPC() {
        return new HuaWeiPC();
    }
}

//小米工厂--可以生成小米手机和小米PC
class AppleFactory implements AbstractFactory{

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

    @Override
    public PC createPC() {
        return new MacBook();
    }
}

运行结果:

小米正在通话
小米PC正在打字
华为正在通话
华为PC正在打字
苹果正在通话
MacBook正在打字

以上就是抽象工厂模式。
优点
可以针对产品族类型的需求进行品牌或类型的扩展
缺点
产品族中的产品不变动,如果添加或者删除一个产品,则所有的子类工厂全部需要修改相应内容。常用在产品族中产品内容不变的需求中。

总结:

  1. 简单工厂:就是给正常创建类简单进行了一层封装,能够封装产品的生产过程。
  2. 静态工厂:就是用静态方法实现的工厂
  3. 工厂方法:常用于对于单一产品的品牌或类型扩展,但不适用于产品族扩展
  4. 抽象方法:常用来对于产品族中的所有产品进行品牌或类型的扩展,但所有产品族中的产品数量不可变化。

以上内容仅为自己整理记录,如有问题,欢迎讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值