《Head First 设计模式》(四):工厂模式

1.简单工厂模式

简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

注意:

实际上简单工厂不是一个设计模式,更多程度上比较像一种编程习惯。

结构图:

  • Factory:工厂类,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象
  • IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口
  • Product:具体产品类,是简单工厂模式的创建目标

在这里插入图片描述

1.1 示例Demo

IProduct:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: Phone
 * @description: 手机通用规范
 * @author: JiangBeiPing
 * @create: 2021-07-16 09:54
 * @Version: 1.0
 **/
public interface Phone {

    void make();

}

Product:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: MiPhone
 * @description: 小米手机
 * @author: JiangBeiPing
 * @create: 2021-07-16 09:56
 * @Version: 1.0
 **/
public class MiPhone implements Phone{
    public MiPhone() {
        make();
    }

    @Override
    public void make() {
        System.out.println("生产一台小米手机");
    }
}

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: VideoPhone
 * @description: VO手机
 * @author: JiangBeiPing
 * @create: 2021-07-16 09:58
 * @Version: 1.0
 **/
public class VideoPhone implements Phone{

    public VideoPhone() {
        make();
    }

    @Override
    public void make() {
        System.out.println("生产一台VO手机");
    }
}

Factory:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: PhoneFactory
 * @description: 手机生产工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 09:59
 * @Version: 1.0
 **/
public class PhoneFactory {

    public Phone makePhone(String phoneType){
        if ("MiPhone".equals(phoneType)){
            return new MiPhone();
        }else if ("VideoPhone".equals(phoneType)){
            return new VideoPhone();
        }
        return null;
    }

}

测试:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: test
 * @description: 测试
 * @author: JiangBeiPing
 * @create: 2021-07-16 10:07
 * @Version: 1.0
 **/
public class test {
    public static void main(String[] args) {
        PhoneFactory phoneFactory = new PhoneFactory();
        Phone miPhone = phoneFactory.makePhone("MiPhone");
    }
}

2. 工厂方法模式

使用OOP的多态性,将工厂和产品都抽象出一个基类,在基类中定义统一的接口,然后在具体的工厂中创建具体的产品。

  • 抽象工厂角色:与应用程序无关,任何在模式中创建对象的工厂必须实现这个接口
  • 具体工厂角色:实现了抽象工厂接口的具体类,含有与引用密切相关的逻辑,并且受到应用程序的调用以创建产品对象
  • 抽象产品角色:工厂方法所创建产品对象的超类型,也就是产品对象的共同父类或共同拥有的接口
  • 具体产品角色:这个角色实现了抽象产品角色所声名的接口。工厂方法所创建的每个具体产
  • 品对象都是某个具体产品角色的实例
2.1 示例Demo

AbstractFactory类:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: AbstractFactory
 * @description: 抽象工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:39
 * @Version: 1.0
 **/
public interface AbstractFactory {

    Phone makePhone();

}

具体工厂角色:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: MiFactory
 * @description: 小米手机制造工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:44
 * @Version: 1.0
 **/
public class MiFactory implements AbstractFactory{

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

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: VideoFactory
 * @description: 制造vo手机的工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:46
 * @Version: 1.0
 **/
public class VideoFactory implements AbstractFactory{

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

测试:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: test
 * @description: 测试
 * @author: JiangBeiPing
 * @create: 2021-07-16 10:07
 * @Version: 1.0
 **/
public class test {
    public static void main(String[] args) {
        // 简单工厂模式
        PhoneFactory phoneFactory = new PhoneFactory();
        Phone miPhone = phoneFactory.makePhone("MiPhone");

        // 工厂方法模式
        AbstractFactory miFactory = new MiFactory();
        AbstractFactory videoFactory = new VideoFactory();
        miFactory.makePhone();
        videoFactory.makePhone();
    }
}

2.2 优缺点

优点:

  1. 子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现
  2. 屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化
  3. 降低了工厂类的内聚,满足了类之间的层次关系,又很好的符合了面向对象设计中的单一职责原则,这样有利于程序的拓展

缺点:

  1. 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度
  2. 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度
  3. 一个具体工厂只能创建一种具体产品

3. 抽象工厂模式

抽象工厂是指一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象

以生产手机和电脑为例说明,我们需要一个抽象工厂下面有两个子工厂,一个叫做手机工厂(PhoneFactory)用于生产手机,一个叫做电脑工厂(PcFactory),用于生产电脑。

抽象工厂与工厂方法的区别是,工厂方法中的具体工厂一般只生产一个或几个对象,而抽象工厂中的具体工厂生产的是一族对象。

  • 抽象工厂(Abstract Factory)角色: 担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的
  • 具体工厂(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的
  • 抽象产品(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口
  • 具体产品(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑
3.1 示例Demo

抽象工厂(Abstract Factory)角色:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: AbstractFactory
 * @description: 抽象工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:39
 * @Version: 1.0
 **/
public interface AbstractFactory {

    Phone makePhone();

    AbstractPc makePc();

}

具体工厂(Concrete Factory)角色:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: MiFactory
 * @description: 小米手机制造工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:44
 * @Version: 1.0
 **/
public class MiFactory implements AbstractFactory{

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

    @Override
    public AbstractPc makePc() {
        return new MiPc();
    }
}

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: VideoFactory
 * @description: 制造vo手机的工厂
 * @author: JiangBeiPing
 * @create: 2021-07-16 15:46
 * @Version: 1.0
 **/
public class VideoFactory implements AbstractFactory{

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

    @Override
    public AbstractPc makePc() {
        return new VideoPc();
    }
}

抽象产品(Abstract Product)角色:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: AbstractPc
 * @description: 电脑统一规范接口
 * @author: JiangBeiPing
 * @create: 2021-07-16 16:37
 * @Version: 1.0
 **/
public interface AbstractPc {

    void make();

}

具体产品(Concrete Product)角色:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: MiPc
 * @description: 小米电脑
 * @author: JiangBeiPing
 * @create: 2021-07-16 16:38
 * @Version: 1.0
 **/
public class MiPc implements AbstractPc{

    public MiPc() {
        make();
    }

    @Override
    public void make() {
        System.out.println("生产一台小米电脑");
    }
}

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: VideoPc
 * @description: vo电脑
 * @author: JiangBeiPing
 * @create: 2021-07-16 16:39
 * @Version: 1.0
 **/
public class VideoPc implements AbstractPc{

    public VideoPc() {
        make();
    }

    @Override
    public void make() {
        System.out.println("生产一台vo电脑");
    }
}

测试:

package com.jbp.designpattern.factory.simplefactory;

/**
 * @ClassName: test
 * @description: 测试
 * @author: JiangBeiPing
 * @create: 2021-07-16 10:07
 * @Version: 1.0
 **/
public class test {
    public static void main(String[] args) {
        // 简单工厂模式
        PhoneFactory phoneFactory = new PhoneFactory();
        Phone miPhone = phoneFactory.makePhone("MiPhone");

        // 工厂方法模式
        AbstractFactory miFactory = new MiFactory();
        AbstractFactory videoFactory = new VideoFactory();
        miFactory.makePhone();
        videoFactory.makePhone();

        // 抽象工厂模式
        miFactory.makePc();
        videoFactory.makePc();
    }
}

3.2 使用场景
  • 系统要求不依赖于产品类实例如何被创建、组合和表达的细节
  • 系统有多于一个的产品族,而系统只消费其中某一产品族
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现
3.3 抽象工厂模式与工厂方法模式的区别
  1. 工厂方法模式:每个抽象产品派生多个具体产品类,每个抽象工厂类派生多个具体工厂类,每个具体工厂类负责一个具体产品的实例创建
  2. 抽象工厂模式:每个抽象工厂派生多个具体工厂类,每个具体工厂负责多个(一系列)具体产品的实例创建
3.4 优缺点

优点:

  1. 抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建
  2. 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
  3. 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”

缺点:

  1. 增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值