抽象工厂模式

        抽象工厂模式是围绕一个超级工厂创建其他工厂,该超级工厂又称为工厂的工厂。

在工厂方法模式中,我们使用一个工厂创建一个产品,一个具体的工厂对应一个具体的产品,但当我们需要一个工厂能够提供多个产品对象,这个时候就需要抽象工厂模式了

在学习之前,先了解一下产品等级和产品组的概念:

  • 产品族:是一个品牌下的一系列产品,比如华为下面有手机,路由器,电脑,都称为华为的产品族。
  • 产品等级:多个品牌之间的小米和华为的路由器就是称为一个等级。

同一个形状的是同一个产品等级,同一个颜色是同一个产品族。

1.UML图

以下图为例,有手机和路由器两种产品,有华为和小米两种品牌,两种品牌都可以生产手机和路由器;

  1. 有手机和路由器两种产品,定义两个接口;

  2. 小米和华为都可以生产这两种产品,所以有4个实现类;

  3. 现在需要创建华为和小米的工厂类,先将工厂类进行抽象,里面有创建两个产品的方法,返回的是产品的接口类;

  4. 创建华为和小米的工厂实现类,继承工厂类接口,实现创建各自产品的方法;

  5. 客户端调用时,直接用工厂接口类创建需要的工厂,拿到对应的产品;

2.代码实现

手机和路由器的接口

//手机产品接口
public interface IPhoneProduct {
    //开机
    void start();
    //关机
    void shutdown();
    //打电话
    void callup();
    //发邮件
    void sendSMS();
}

//路由器产品接口
public interface IRouterProduct {
    //开机
    void start();
    //关机
    void shutdown();
    //打开wifi
    void openwifi();
    //设置
    void setting();
}

华为和小米的产品的四个实现类

//华为手机实现类
public class HuaweiPhone implements IPhoneProduct {

    @Override
    public void start() {
	System.out.println("开启华为手机");
    }

    @Override
    public void shutdown() {
	System.out.println("关闭华为手机");
    }

    @Override
    public void callup() {
	System.out.println("华为手机打电话");
    }

    @Override
    public void sendSMS() {
	System.out.println("华为手机发邮件");
    }
}

//华为路由器实现类
public class HuaweiRouter implements IRouterProduct {

    @Override
    public void start() {
        System.out.println("开启华为路由器");
    }

    @Override
    public void shutdown() {
	System.out.println("关闭华为路由器");
    }

    @Override
        public void openwifi() {
	System.out.println("打开华为wifi");
    }

    @Override
    public void setting() {
	System.out.println("设置华为路由器");
    }
}

//小米手机实现类
public class XiaomiPhone implements IPhoneProduct {

    @Override
    public void start() {
	System.out.println("开启小米手机");
    }

    @Override
    public void shutdown() {
	System.out.println("关闭小米手机");
    }

    @Override
    public void callup() {
	System.out.println("小米手机打电话");
    }

    @Override
    public void sendSMS() {
	System.out.println("小米手机发邮件");
    }
}

//小米路由器实现类
public class XiaomiRouter implements IRouterProduct {

    @Override
    public void start() {
	System.out.println("开启小米路由器");
    }

    @Override
    public void shutdown() {
	System.out.println("关闭小米路由器");
    }

    @Override
    public void openwifi() {
	System.out.println("打开小米wifi");
    }

    @Override
    public void setting() {
	System.out.println("设置小米路由器");
    }
}

工厂接口

//产品工厂接口
public interface IProductFactory {

    //生产手机
    IPhoneProduct phoneProduct();

    //生成路由器
    IRouterProduct routerProduct();
}

4.华为和小米实现类,继承工厂接口

//华为工厂实现类
public class HuaweiFactory implements IProductFactory {

    @Override
    public IPhoneProduct phoneProduct() {
	return new HuaweiPhone();
    }

    @Override
    public IRouterProduct routerProduct() {
	return new HuaweiRouter();
    }
}

//小米工厂实现类
public class XiaomiFactory implements IProductFactory {

    @Override
    public IPhoneProduct phoneProduct() {
    	return new XiaomiPhone();
    }

    @Override
    public IRouterProduct routerProduct() {
	return new XiaomiRouter();
    }
}

5.客户端通过IProductFactory 创建各自的工厂,通过工厂拿到对应品牌的产品

public class Client {
    
    public static void main(String[] args) {
        
	System.out.println("============小米产品============");
	//创建小米工厂
	IProductFactory xiaomiFactory = new XiaomiFactory();

	//生产小米手机
	IPhoneProduct xiaomiPhone = xiaomiFactory.phoneProduct();
	xiaomiPhone.start();
	xiaomiPhone.sendSMS();

	//生产小米路由器
	IRouterProduct xiaomiRouter = xiaomiFactory.routerProduct();
	xiaomiRouter.openwifi();
	xiaomiRouter.setting();

	System.out.println("============华为产品============");
	//创建华为工厂
	IProductFactory huaweiFactory = new HuaweiFactory();

	//生产华为手机
	IPhoneProduct huaweiPhone = huaweiFactory.phoneProduct();
	huaweiPhone.start();
	huaweiPhone.sendSMS();

	//生产华为路由器
	IRouterProduct huaweiRouter = huaweiFactory.routerProduct();
	huaweiRouter.openwifi();
	huaweiRouter.setting();
    }
}

        抽象工厂模式的实现就是这样,还记得前面讲的产品族和产品等级的概念吗,如果新增一个产品族或产品等级会怎样?

拓展一个产品族

我们会发现,拓展一个产品族是非常困难的,例如产品族中新增一个笔记本电脑,也就是说华为和小米现在可以生产电脑了,如下图所示(黄色字体为新增一个产品族需要做的事),对顶层的工厂接口类也要修改,这是非常麻烦的;

拓展一个产品等级

如果扩展一个产品等级,例如新增一个手机,也就是说新增一个品牌来生产手机,如下图所示(黄色字体为新增一个产品等级需要做的事),新增一个产品等级不用修改原来的代码,符合OCP原则,这是非常舒服的;

优点:

一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象(将一个系列的产品统一一起创建);

缺点:
  • 产品族扩展非常困难,要增加一个系列的某一产品,既要修改工厂抽象类里加代码,又修改具体的实现类里面加代码;

  • 增加了系统的抽象性和理解难度;

适用场景
  • 一系列相关产品对象(属于同一产品族)一起创建时需要大量的重复代码;

  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现;

抽象工厂模式符合依赖抽象原则

  • 创建对象实例时,不要直接 new一个对象, 而是把创建对象的动作放在一个工厂的方法中;

  • 不要让类继承具体类,而是继承抽象类或者是实现接口;

  • 不要覆盖基类中已经实现的方法;

  • 38
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五敷有你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值