设计模式之抽象工厂模式

抽象工厂模式的定义

“Provide an interface for creating families of related or dependent objects without specifying their concrete classes. ”
(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定他们的具体类。)

抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
抽象工厂模式


package com.example.demo.designpatterns;
public class AbstractFactory {
    public static void main(String[] args) {
        HumanFactory maleHumanFactory = new MaleHumanFactory();
        Human maleBlankHuman = maleHumanFactory.createBlankHuman();
        maleBlankHuman.color();
        maleBlankHuman.say();
        maleBlankHuman.getSex();

        HumanFactory femaleHumanFactory = new FemaleHumanFactory();
        Human femaleBlankHuman = femaleHumanFactory.createBlankHuman();
        femaleBlankHuman.color();
        femaleBlankHuman.say();
        femaleBlankHuman.getSex();
    }
}
interface Human{
    void color();
    void say();
    void getSex();
}
abstract class WhiteHuman implements Human{
    @Override
    public void color(){
        System.out.println("白人是白色的");
    }
    @Override
    public void say(){
        System.out.println("白人一般说英语");
    }
}
class MaleWhiteHuman extends WhiteHuman{
    @Override
    public void getSex(){
        System.out.println("我是白人男的");
    }
}
class FemaleWhiteHuman extends WhiteHuman{
    @Override
    public void getSex(){
        System.out.println("我是白人女的");
    }
}
abstract class BlankHuman implements Human{
    @Override
    public void color(){
        System.out.println("黑人是黑色的");
    }
    @Override
    public void say(){
        System.out.println("黑人一般也说英语");
    }
}
class MaleBlankHuman extends BlankHuman{
    @Override
    public void getSex(){
        System.out.println("我是黑人男的");
    }
}
class FemaleBlankHuman extends BlankHuman{
    @Override
    public void getSex(){
        System.out.println("我是黑人女的");
    }
}
abstract class YellowHuman implements Human{
    @Override
    public void color(){
        System.out.println("黄人是黄色的");
    }
    @Override
    public void say(){
        System.out.println("黄人一般说汉语");
    }
}
class MaleYellowHuman extends YellowHuman{
    @Override
    public void getSex(){
        System.out.println("我是黄人男的");
    }
}
class FemaleYellowHuman extends YellowHuman{
    @Override
    public void getSex(){
        System.out.println("我是黄人女的");
    }
}
interface HumanFactory{
    Human createWhiteHuman();
    Human createBlankHuman();
    Human createYellowHuman();
}
class MaleHumanFactory implements HumanFactory{
    @Override
    public Human createWhiteHuman() {
        return new MaleWhiteHuman();
    }
    @Override
    public Human createBlankHuman() {
        return new MaleBlankHuman();
    }
    @Override
    public Human createYellowHuman() {
        return new MaleYellowHuman();
    }
}
class FemaleHumanFactory implements HumanFactory{
    @Override
    public Human createWhiteHuman() {
        return new FemaleWhiteHuman();
    }
    @Override
    public Human createBlankHuman() {
        return new FemaleBlankHuman();
    }
    @Override
    public Human createYellowHuman() {
        return new FemaleYellowHuman();
    }
}

抽象工厂模式的应用

  • 抽象工厂模式的优点
    Ⅰ.封装性,每个产品的实现类不是高层模块要关心的,他要关系的是什么?是接口,是抽象,他不关心对象是如何创建出来的,这个交给工厂类来负责。
    Ⅱ.产品族内的约束为非公开状态。产品族内的约束对高层模块来说是透明的,他不需要知道这个约束,具体的产品族内的约束是在工厂内实现的。

  • 抽象工厂模式的缺点
    Ⅰ.抽象工厂模式最大的缺点就是产品族扩展非常困难。比如说上面的代码例子,如果需要增加另外一个棕色的人,需要在HumanFactory里面添加一个方法,还需要在两个创建人类的子类工厂里面添加相应的实现,另外还需要添加两个棕色人实现类。这违背了我们的开闭原则。

  • 抽象工厂模式的使用场景
    Ⅰ.一个对象族都有相同的约束,则可以使用抽象工厂模式。例如一个文本编辑器和一个图片处理器,都是软件实体,但是*nix的文本编辑器和Windows下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也是类似的状态。也就是具有了相同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。

抽象工厂模式的注意事项

在抽象工厂模式的缺点中,我们提到抽象工厂的产品族扩展比较困难,但是一定要清楚,是产品族扩展困难,而不是产品等级。在该模式下,产品等级是非常容易扩展的,增加一个产品等级,只要增加一个工厂类负责新增加出来的产品生产任务即可。也就是说横向扩展容易,纵向扩展困难。比如说除了男人女人,还有中性人,这个就比较好扩展了,增加三个产品类,分别对应不同的肤色,然后再创建一个工厂类,专门负责创建中性人,完全通过扩展类实现业务需求的变更,从这点来看,抽象工厂是符合开闭原则的。

抽象工厂模式的最佳实践

抽象工厂是一个简单的模式,使用的场景非常多,在软件产品开发过程中,涉及到不同操作系统的时候,都可以考虑使用抽象工厂模式,例如一个应用,它需要在三个不同的平台(Windows、Linux、Android)上运行,我们该怎么设计?我们可以通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI应该都是非常类似的,唯一不同的就是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值