设计模式创建型——抽象工厂模式

设计模式创建型——抽象工厂模式 目录什么是抽象工厂模式抽象工厂模式的实现工厂方法模式角色抽象工厂模式类图抽象工厂模式代码实现抽象工厂模式的特点优点缺点使用场景注意事项实际应用什么是抽象工厂模式抽象工厂模式Abstract Factory Pattern隶属于设计模式中的创建型模式用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口使客户端在不必指定产品的具体情况下创建多个产品族中的产品对象。在介绍抽象工厂模式前我们先厘清两个概念产品等级结构产品等级结构指的是产品的继承结构例如一个汽车抽象类它有蔚来汽车、特斯拉汽车、比亚迪汽车等一系列的子类那么这个汽车抽象类和他的子类就构成了一个产品等级结构。产品族产品族是指由同一个工厂生产的位于不同产品等级结构中的一组产品。比如比亚迪工厂生产唐、宋那么唐、宋则位于空调产品族中。抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时通过抽象工厂模式能够保证客户端始终只使用同一个产品族中的对象并且通过隔离具体类的生成使得客户端不需要明确指定具体生成类所有的具体工厂都实现了抽象工厂中定义的公共接口因此只需要改变具体工厂的实例就可以在某种程度上改变整个软件系统的行为。但该模式的缺点在于添加新的行为时比较麻烦如果需要添加一个新产品族对象时需要更改接口及其下所有子类这必然会带来很大的麻烦。抽象工厂模式的实现工厂方法模式角色抽象工厂角色Abstract Factory描述具体工厂的公共接口是具体工厂的父类。具体工厂角色Concrete Factory描述具体工厂创建产品的实例供外界调用主要实现了抽象工厂中的抽象方法完成具体产品的创建。抽象产品角色Product抽象产品角色是简单工厂模式所创建的所有对象的父类,负责描述所有实例所共有的公共接口它的引入将提高系统的灵活性使得在工厂类中只需定义一个工厂方法因为所有创建的具体产品对象都是其子类对象。具体产品角色Concrete Product具体产品角色是简单工厂模式的创建目标所有创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色需要实现定义在抽象产品中的抽象方法由具体工厂来创建它同具体工厂之间一一对应。抽象工厂模式类图抽象工厂模式代码实现抽象产品角色/** * author Evan Walker * version 1.0 * desc 昂焱数据: https://www.ayshuju.com * date 2023/04/04 13:41:41 */ public interface Color { String getColor(); } public interface Taste { String getTaste(); }具体产品角色* author Evan Walker * version 1.0 * desc 昂焱数据: https://www.ayshuju.com * date 2023/04/04 13:42:21 */ public class Apple implements Color { Override public String getColor() { return 红色; } } public class Orange implements Color { Override public String getColor() { return 橙色; } } public class Pear implements Color { Override public String getColor() { return 黄色; } } public class Coke implements Taste { Override public String getTaste() { return 好喝打嗝; } } public class Milk implements Taste { Override public String getTaste() { return 香; } } public class Wine implements Taste { Override public String getTaste() { return 好喝上头; } }抽象工厂角色/** * author Evan Walker * version 1.0 * desc 昂焱数据: https://www.ayshuju.com * date 2023/04/06 13:58:37 */ public abstract class AbstractFactory { public abstract Color getColor(String name); public abstract Taste getTaste(String name); }具体工厂角色/** * author Evan Walker * version 1.0 * desc 昂焱数据: https://www.ayshuju.com * date 2023/04/06 14:44:44 */ public class ColorFactory extends AbstractFactory { Override public Color getColor(String name) { if(name null){ return null; } if(name.equalsIgnoreCase(APPLE)){ return new Apple(); } else if(name.equalsIgnoreCase(ORANGE)){ return new Orange(); } else if(name.equalsIgnoreCase(PEAR)){ return new Pear(); } return null; } Override public Taste getTaste(String taste) { return null; } } public class TasteFactory extends AbstractFactory { Override public Color getColor(String name) { return null; } Override public Taste getTaste(String name) { if(name null){ return null; } if(name.equalsIgnoreCase(MILK)){ return new Milk(); } else if(name.equalsIgnoreCase(WINE)){ return new Wine(); } else if(name.equalsIgnoreCase(COKE)){ return new Coke(); } return null; } }创建一个工厂创造器/生成器类通过传递形状或颜色信息来获取工厂并进行测试。/** * author Evan Walker * version 1.0 * desc 昂焱数据: https://www.ayshuju.com * date 2023/04/06 15:45:51 */ public class FactoryProducer { public static AbstractFactory getFactory(String choice){ if(choice.equalsIgnoreCase(TASTE)){ return new TasteFactory(); } else if(choice.equalsIgnoreCase(COLOR)){ return new ColorFactory(); } return null; } }/** * author Evan Walker * version 1.0 * desc * date 2023/04/04 14:02:43 */ public class Test { public static void main(String[] args) { //获取味道工厂 AbstractFactory tasteFactory FactoryProducer.getFactory(Taste); Taste taste tasteFactory.getTaste(Wine); System.out.println(taste.getTaste()); taste tasteFactory.getTaste(milk); System.out.println(taste.getTaste()); taste tasteFactory.getTaste(COKE); System.out.println(taste.getTaste()); //获取颜色工厂 AbstractFactory colorFactory FactoryProducer.getFactory(Color); Color color colorFactory.getColor(apple); color.getColor(); System.out.println(color.getColor()); color colorFactory.getColor(orange); System.out.println(color.getColor()); color colorFactory.getColor(pear); System.out.println(color.getColor()); } }抽象工厂模式的特点优点提供了一种封装对象创建过程的方式抽象工厂模式将对象的创建过程封装在了具体的工厂类中客户端只需要关注工厂接口和产品接口无需关心具体的实现细节。实现了产品族的切换通过使用不同的具体工厂类可以方便地切换整个产品族的产品从而实现了接口与实现的分离。保持了代码的一致性抽象工厂模式保持了一致性即所有由同一工厂创建的产品都相互关联使得产品之间可以很方便地进行配合使用。缺点不易扩展新的产品当需要给产品家族新增一个产品时需要修改抽象工厂的接口及所有的具体工厂类这就违反了开闭原则增加了代码的维护成本。增加了系统的复杂度抽象工厂模式引入了多个抽象和具体类增加了系统的复杂度和理解难度。使用场景必须创建一系列相互关联或相互依赖的产品对象。需要提供一个统一的接口将客户端与具体实现解耦。需要在运行时切换不同的产品族。注意事项注意抽象工厂接口的设计应该根据业务需求合理定义所需方法。了解产品族和产品等级结构之间的关系避免设计出不符合实际需求的工厂类结构。实际应用GUI工具包不同的操作系统如Windows、Linux提供了不同的GUI工具包抽象工厂模式可以用于创建具体的按钮、文本框等GUI组件。数据库访问数据库访问框架可以根据配置文件或运行时参数选择不同的数据库访问驱动抽象工厂模式可以用于创建不同类型的数据库连接和操作对象。游戏开发在游戏开发中可以使用抽象工厂模式来创建不同种类的角色、武器、装备等物品。