1.业务需求
大家好,我是菠菜啊。今天给大家介绍工厂三兄弟最后一个兄弟——抽象工厂。老规矩,在介绍这期抽象工厂模式前,我们先来看看这样的需求:现在有俩个制造工厂,都要生产冰箱产品,并且客户在使用冰箱产品能够随意切换制造厂商,我们该怎么设计?
2.代码实现
实现初步思路:
上一章我们学习了工厂方法模式(看这篇文章前可以先回顾《设计模式——工厂三兄弟之工厂方法》这篇),所有我们有了第一版思路。
工厂方法模式:
实现代码结构图:
IFactory接口:
public interface IFactory {
public IIceboxProduct createIceboxProduct();
}
HRFactory类:
public class HRFactory implements IFactory {
@Override
public IIceboxProduct createIceboxProduct() {
return new HRIceboxProduct();
}
}
MDFactory类:
public class MDFactory implements IFactory {
@Override
public IIceboxProduct createIceboxProduct() {
return new MDIceboxProduct();
}
}
IIceboxProduct(冰箱产品)接口:
//冰箱产品
public interface IIceboxProduct {
//制冷
public void freezing(Object things);
//保鲜
public void keeepFresh(Object things);
}
HRIceboxProduct类:
public class HRIceboxProduct implements IIceboxProduct {
@Override
public void freezing(Object things) {
System.out.println("海尔冰箱食物制冷");
}
@Override
public void keeepFresh(Object things) {
System.out.println("海尔冰箱食物保鲜");
}
}
MDIceboxProduct类:
public class MDIceboxProduct implements IIceboxProduct {
@Override
public void freezing(Object things) {
System.out.println("美的冰箱食物制冷");
}
@Override
public void keeepFresh(Object things) {
System.out.println("美的冰箱食物保鲜");
}
}
client类:
public class Client {
public static void main(String[] args) {
//IFactory factory=new HRFactory();
IFactory factory=new MDFactory();
IIceboxProduct icebox=factory.createIceboxProduct();
icebox.freezing("冷饮");
icebox.keeepFresh("水果");
}
}
思考:上述代码是按照工厂方法模式来设计的,如果我们想把海尔冰箱换成美的冰箱,只要修改IFactory factory=new MDFactory()这里即可,让工厂子类决定实例化哪个冰箱产品,工厂方法使一个类的实例化延迟到其子类。
3.需求升级
这个俩个工厂现在不单单生产冰箱,还要生产空调,那么该怎么实现呢? 很简单,直接增加相应的产品不就行了。
实现代码结构图:
IFactory接口:
public interface IFactory {
public IIceboxProduct createIceboxProduct();
//新增空调产品制造接口
public IAirConditionerProduct createAirConditionerProduct();
}
HRFactory类:
public class HRFactory implements IFactory {
@Override
public IIceboxProduct createIceboxProduct() {
return new HRIceboxProduct();
}
//新增海尔空调产品制造实现
@Override
public IAirConditionerProduct createAirConditionerProduct() {
return new AirConditionerProduct();
}
}
MDFactory类:
public class MDFactory implements IFactory {
@Override
public IIceboxProduct createIceboxProduct() {
return new MDIceboxProduct();
}
//新增美的空调产品制造实现
@Override
public IAirConditionerProduct createAirConditionerProduct() {
return new MDAirConditionerProduct();
}
}
IAirConditionerProduct接口:
public interface IAirConditionerProduct {
//制冷
public void makeCold();
//制热
public void makeHot();
}
HRAirConditionerProduct类:
public class HRAirConditionerProduct implements IAirConditionerProduct {
@Override
public void makeCold() {
System.out.println("海尔空调制冷");
}
@Override
public void makeHot() {
System.out.println("海尔空调制热");
}
}
MDAirConditionerProduct类:
public class MDAirConditionerProduct implements IAirConditionerProduct {
@Override
public void makeCold() {
System.out.println("美的空调制冷");
}
@Override
public void makeHot() {
System.out.println("美的空调制热");
}
}
client类:
public class Client {
public static void main(String[] args) {
//IFactory factory=new HRFactory();
IFactory factory=new MDFactory();
IIceboxProduct icebox=factory.createIceboxProduct();
icebox.freezing("冷饮");
icebox.keeepFresh("水果");
//新增空调产品
IAirConditionerProduct airConditioner=factory.createAirConditionerProduct();
airConditioner.makeCold();
airConditioner.makeHot();
}
}
思考:抽象工厂接口新增空调产品制造接口,海尔和美的工厂新增空调产品制造实现。新增空调产品抽象接口,新增美的和海尔具体空调产品类。这种设计模式是一种新的设计模式——抽象工厂模式。
4.定义和组成结构
抽象工厂模式(Abstract Factory Pattern)是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。它是工厂方法模式**的一个升级,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
产品等级以及产品族概念:
主要角色和工厂方法模式基本上是一样的,但抽象工厂中方法个数是多个,抽象产品的个数也是多个。
- 抽象工厂(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 CreateProduct() 来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(AbstractProduct):定义了产品的规范,描述了产品的主要特性和功能。(有多个产品级)
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间多对一。
5.优缺点以及应用场景
优点:
- 产品使用者和创建者解耦,无须知道产品的具体创建过程,延续了简单工厂和工厂方法创建者和使用者的分离的优点
- 增强了代码的可扩展性,尤其是增加一个新的产品族,满足开闭原则
- 产品族切换通过使用不同的具体工厂类,保证使用者始终只使用同一个产品族中的对象
缺点:
- 每增加一个新的产品等级就需要修改工厂的抽象层和实现层代码,增加了系统维护成本,违反了开闭原则
- 引入了多个抽象和具体类,增加了系统的复杂度和理解难度
适用场景:
- 使用者只知道创建产品的工厂名,而不知道具体的产品名
- 创建的对象是一系列相互关联或相互依赖的产品族
- 系统中有多个产品族,但是每次只使用一个产品族
现实应用场景:
-
JDBC:数据库连接技术,使用了抽象工厂模式来提供一个标准的接口,可以通过不同的工厂实现类来获取适用于不同数据库类型的 Connection、Statement、ResultSet 等对象,以便实现在不同数据库中切换
-
Spring中的BeanFactory:在 Spring 中,BeanFactory 是用于管理 Bean 的一个工厂,所有工厂都是 BeanFactory 的子类。这样我们可以通过 IOC 容器来管理访问 Bean,根据不同的策略调用 getBean() 方法,从而获得具体对象。
6.工厂三兄弟小结
简单工厂模式适用于创建简单的对象,对象之间有相似的创建过程。工厂方法模式在简单工厂基础上对工厂类进行了抽象,将具体的产品对象创建延迟到具体的工厂子类中,并加入了开闭原则,有一定的可扩展性。抽象工厂模式在工厂方法模式基础上提出产品族的概念,一个工厂能生产同一个产品族的产品。
你的收藏和点赞就是我最大的创作动力,关注我我会持续输出更新!
友情提示:请尊重作者劳动成果,如需转载本博客文章请注明出处!谢谢合作!
【作者:我爱吃菠菜 】