个人主页: danci_
🔥系列专栏:《设计模式》《MYSQL应用》
💪🏻 制定明确可量化的目标,坚持默默的做事。
🚀 转载自文章:探索设计模式的魅力:抽象工厂模式的艺术
探索设计模式的魅力:简单工厂模式-CSDN博客文章浏览阅读2.5k次,点赞58次,收藏46次。实现简单工厂的难点就在于 “如何选择” 实现,前面便子中传递参数的方法, 那都是静态的参数,还可以实现成为动态的参数。客户端通过简单工厂创建 了一个实现接口的对象,然后面向接口编程,从客户端来看,它根本不知道具体的实现是什么,也不知道是如何实现的,它只知道通过工厂获得了一个接口对象 , 然后通过这个接口来获取想要的功能。如果通过客户端的参数来选择具体的实现类,那么就必须让客户端能理解各个参数所代表的具体功能和含义,这样会增加客户端使用的难度,也部分暴露了内部实现,这种情况可以选用可配置的方式来实现。https://blog.csdn.net/danci_/article/details/135566105探索设计模式的魅力:工厂方法模式-CSDN博客文章浏览阅读2.5k次,点赞83次,收藏47次。工厂方法模式是一种创建型设计模式,它提供了一种创建对象的接口,但将具体实例化对象的工作推迟到子类中完成。这样做的目的是创建对象时不用依赖于具体的类,而是依赖于抽象,这提高了系统的灵活性和可扩展性。优点:降低耦合度、增加了系统的可扩展性 和 提高代码的可维护性;缺点:增加了代码的复杂性 和 需要更多的设计考虑。https://blog.csdn.net/danci_/article/details/135611783
目录
一、案例
1.1 示例代码
汽车零件有成百上升个,这里只举例发动机和变速箱。市面上有各种品牌的发动机和变速箱,同一品牌还有各种型等,这里举两个。
1.1.1 简单工厂实现
发动机接口:
public interface EngineApi {
void run();
}
变速箱接口:
public interface GearboxApi {
void run();
}
林肯发动机和林肯变速箱:
public class LinkenEngineApiImpl implements EngineApi {
@Override
public void run() {
System.out.println("林肯发动机工作了");
}
}
public class LinkenGearboxApiImpl implements GearboxApi {
@Override
public void run() {
System.out.println("林肯变速箱工作了");
}
}
丰田发动机和丰田变速箱:
public class ToyotaEngineApiImpl implements EngineApi {
@Override
public void run() {
System.out.println("丰田发动机工作了");
}
}
public class ToyotaGearboxApiImpl implements GearboxApi {
@Override
public void run() {
System.out.println("丰田变速箱工作了");
}
}
发动机工厂:
public class EngineFactory {
public static EngineApi getEngineApi(int i) {
if (i == 1) {
return new LinkenEngineApiImpl();
}
return new ToyotaEngineApiImpl();
}
}
变速箱工厂 :
public class GearboxFactory {
public static GearboxApi getGearbox(int i) {
if (1 == i) {
return new LinkenGearboxApiImpl();
}
return new ToyotaGearboxApiImpl();
}
}
汽车组装类:
public class CarEngineer {
public void makeCar(int engineType, int gearboxType) {
EngineApi engineApi = EngineFactory.getEngineApi(engineType);
GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);
engineApi.run();
gearbox.run();
}
}
客户端:
public class CarClient {
public static void main(String[] args) {
CarEngineer carEngineer = new CarEngineer();
carEngineer.makeCar(1, 1);
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了
修改客户端carEngineer.makeCar(1, 2); 运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
丰田变速箱工作了
1.1.2 问题
修改了产数之后,组装的汽车使用了林肯的发动机,而变速箱是丰田的,此时发动机与变速箱不是一个品牌,如果发动机与变速箱不匹配无法正常配合工作,那么组装的这个汽车就等于废了(这里假设只有同品牌的零部件才能正常配合动作)。
显然发动机与变速箱是需要互相匹配,强依赖关系。就是选了这个发动机就必须选定某个变速箱。抽象工厂来解决这个问题。
1.1.3 抽象工厂实现
解决1.1.2问题是要创建一序列有相互依赖关联和相互约束的产品——抽象工厂模式。
代码改造:
发动机接口和变速箱接口不变:
public interface EngineApi {
void run();
}
public interface GearboxApi {
void run();
}
发动机和变速箱的实现也不变:
public class LinkenEngineApiImpl implements EngineApi {
@Override
public void run() {
System.out.println("林肯发动机工作了");
}
}
public class LinkenGearboxApiImpl implements GearboxApi {
@Override
public void run() {
System.out.println("林肯变速箱工作了");
}
}
public class ToyotaEngineApiImpl implements EngineApi {
@Override
public void run() {
System.out.println("丰田发动机工作了");
}
}
public class ToyotaGearboxApiImpl implements GearboxApi {
@Override
public void run() {
System.out.println("丰田变速箱工作了");
}
}
添加抽象工厂:(工厂抽象出来)
public interface AbstractFactory {
/**
* 创建发动机 <br/>
*/
EngineApi createLinken();
/**
* 创建变速箱 <br/>
*/
GearboxApi createGearbox();
}
发动机工厂修改为林肯工厂,并实现抽象工厂:(//注释部分为简单工厂代码)
public class LinkenFactory implements AbstractFactory {
//public class EngineFactory {
/**
* 生产林肯发动机
*/
@Override
public EngineApi createLinken() {
return new LinkenEngineApiImpl();
}
/**
* 生产林肯发变速箱
*/
@Override
public GearboxApi createGearbox() {
return new LinkenGearboxApiImpl();
}
//public static EngineApi getEngineApi(int i) {
// if (i == 1) {
// return new LinkenEngineApiImpl();
// }
//
// return new ToyotaEngineApiImpl();
//}
}
变速箱工厂修改为丰田工厂,并实现抽象工厂:(//注释部分为简单工厂代码)
public class ToyotaFactory implements AbstractFactory {
//public class GearboxFactory {
/**
* 生产丰田发动机
*/
@Override
public EngineApi createLinken() {
return new ToyotaEngineApiImpl();
}
/**
* 生产丰田变事箱
*/
@Override
public GearboxApi createGearbox() {
return new ToyotaGearboxApiImpl();
}
//public static GearboxApi getGearbox(int i) {
// if (1 == i) {
// return new LinkenGearboxApiImpl();
// }
//
// return new ToyotaGearboxApiImpl();
//}
}
汽车组装类有修改:(//注释部分为简单工厂代码)
public class CarEngineer {
/**
* 接收选择好的哪一个序列产品工厂
* @param factory
*/
public void makeCar(AbstractFactory factory) {
EngineApi engineApi = factory.createLinken();
GearboxApi gearbox = factory.createGearbox();
engineApi.run();
gearbox.run();
}
//public void makeCar(int engineType, int gearboxType) {
// EngineApi engineApi = EngineFactory.getEngineApi(engineType);
// GearboxApi gearbox = GearboxFactory.getGearbox(gearboxType);
// engineApi.run();
// gearbox.run();
//}
}
客户端:(//注释部分为简单工厂代码)
public class CarClient {
public static void main(String[] args) {
//CarEngineer carEngineer = new CarEngineer();
//carEngineer.makeCar(1, 2);
CarEngineer carEngineer = new CarEngineer();
// 传入选中的哪种产品工厂
carEngineer.makeCar(new LinkenFactory());
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
林肯发动机工作了
林肯变速箱工作了
修改选中的产品工厂carEngineer.makeCar(new ToyotaFactory()) ,运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_311.jdk/...
丰田发动机工作了
丰田变速箱工作了
这个抽象工厂相当于选择一套方案,方案确定好,里面的零件也就确定好了。不用一个零件一个零件的选择以免选择出错。
二、模式讲解
2.1 功能
2.2 抽象工厂模式的结构及说明
2.3 示例代码程序结构图
抽象工厂模式主要用于以下几个方面的应用场景中:
优势方面,抽象工厂模式具有以下几个优势:
2.4 抽象工厂模式与简单工厂模式