抽象工厂模式

介绍

抽象工厂可以看成是由于产品类又被抽象的结果,在工厂模式中工厂能生产一种产品类(产品簇)的一系列产品,但是如果每一个产品类又有着进一步的分类便需要进一步抽象,例如工厂能生产多种程序员,但是每个程序员又有了程序员主体和程序员细节的划分,便需要抽象工厂了

具体实现

角色划分

ProductApi:生产者API,用于定义生产者的行为规范,即抽象接口

ConcreteProduct:生产者角色,具体已经实现接口的生产者

ProductFactory:抽象的工厂,创建不同产品类的工厂(字节类和阿里类)

ConcreteFactory:具体的工厂,负责具体的某个产品类的产品的加工(程序员1和程序员2)

Client:消费者,需要使用具体的某个生产者

代码实现

ProductApi类

public interface ProgrammerDetail {
    void detailLife();
}
public interface Programmer {
    void dayLife();
}

ProductRole

public class Programmer1 implements Programmer{

    @Override
    public void dayLife() {
        System.out.println("程序员1:起床-敲代码-吃饭-逛街-睡觉");
    }
}
public class Programmer2 implements Programmer{

    @Override
    public void dayLife() {
        System.out.println("程序员2:起床-敲代码-吃饭-逛街-睡觉");
    }
}
public class Programmer1Detail implements ProgrammerDetail {

    @Override
    public void detailLife() {
        System.out.println("逛街是自己逛街");
    }
}
public class Programmer2Detail implements ProgrammerDetail {
    @Override
    public void detailLife() {
        System.out.println("逛街是陪女朋友逛街");
    }
}

ProductFactory

public abstract class ProgrammerFactory {

    public abstract Programmer getProgrammer();

    public abstract ProgrammerDetail getDetail();
}

ConcreteFactory(具体的工厂)

public class Programmer1Factory extends ProgrammerFactory {

    @Override
    public Programmer getProgrammer() {
        return new Programmer1();
    }

    @Override
    public ProgrammerDetail getDetail() {
        return new Programmer1Detail();
    }
}
public class Programmer2Factory extends ProgrammerFactory {
    @Override
    public Programmer getProgrammer() {
        return new Programmer2();
    }

    @Override
    public ProgrammerDetail getDetail() {
        return new Programmer2Detail();
    }
}

Client(用于测试的消费者1)

public class Client1 {
    public static void main(String[] args) {
        ProgrammerFactory programmerFactory = new Programmer2Factory();
        Programmer programmer = programmerFactory.getProgrammer();
        ProgrammerDetail detail = programmerFactory.getDetail();
        programmer.dayLife();
        detail.detailLife();
    }
}

在这里插入图片描述

事实上我这个例子也举的不太友好,下面再拿个《研磨设计模式》中的例子解释下

在这里插入图片描述

有两个产品类订单主体和订单细节,两个产品簇数据库存储和Xml存储

扩展产品簇时很容易比如再加个本地缓存存储,直接写个CacheFactory实现DAOFactory接口,然后完善两个方法

扩展产品类就不容易了,比如再加个订单简介,那么所有的子类factory都需要实现一个新方法

优缺点

优点

使得切换产品簇变得容易

因为一个具体的工厂实现代表的是一个产品簇,比如上面例子的程序员中程序员1代表方案一:程序员1的日常生活和细节生活,如果要切换成为程序员2,那就变成了方案二:程序员2的日常生活和细节生活

客户端选用不同的工厂实现,就相当于是在切换不同的产品簇

缺点

切换产品簇容易,但是扩展产品簇下的新产品便不容易,比如再扩展一个ProgrammerPrivacy(程序员隐私)接口,那么抽象工厂需要增加一个抽象方法返回该类,那么抽象类的所有子类都需要多加一个方法

在使用抽象工厂模式的时候,如果需要选择的层次过多,那么会造成整个类层次变得复杂,也就是产品簇上还有产品簇,有点套娃的意思,层次多了非常容易出错

讨论工厂方法与抽象工厂

此处可先看上一篇博客工厂模式的JDK源码分析部分工厂模式

笔者关于这里的区别确实是思考了很久不得解,知道看了JDK源码的设计模式才恍然大悟(JDK才是永远的神)

在Calendar中可以看出工厂模式的工厂也能有多个方法,但是这些方法返回值大多是一个对象,即使不是大多目的也是为了更好的创建那一个对象(比如Calendar中有大量返回内部类Builder的方法,Builder也是用来更好的创建Calendar的),所以工厂类的职责自始至终都是专注于创建一个对象;然而我们来看抽象工厂却不是这样,抽象工厂的每个方法都可以是不同的对象,也就是说抽象工厂类的职责是创建多个对象。如果说工厂模式是用多种方法来完善一个产品类,那么抽象工厂使用多种方法创建多个产品来完善一个产品簇

理解了这个,不难想到,我们还可以将抽象工厂与工厂方法结合使用,将抽象工厂的一个子类工厂当成工厂模式的抽象工厂再抛给子类去实现,比如将上文的RdbDaoFactory做成抽象的,写两个子类RdbOrderMainFactory和RdbOrderDetailFactory,两个子类专注于一个产品的创建。当然这样做像套娃一样,系统复杂度会提高很多,一定要结合业务,且行且珍惜

注意点

当抽象工厂模式只需要加工一个产品,即只有一个方法,那么事实上就退化成了工厂模式而已

选用时机

如果一个系统要由多个产品系列中的一个来配置的时候。换句话说,就是可以动态地切换产品簇的时候使用

总的来说抽象工厂更重视有着多个产品簇的划分,每个产品簇都有着自己的多个产品

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值