抽象工厂 设计模式
抽象⼯⼚模式,所要解决是⼀个产品族问题。这种场景在业务开发中也是⾮常多⻅的,只不过可能有时候没有将它们抽象出来。
可能代码被 if else埋上了,当我们知道在什么场景下可以用抽象工厂优化的时候,那么代码的层级结构可以被很好的完善,应对业务需求变化也提供良好的扩展性和优雅度。
抽象工厂模式:提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。
(1)AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
(2)ConcreateFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
(3)AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的的业务方法。
(4)ConcreteProduct(具体产品):它定义了具体工厂生产的具体产品对象,实现了抽象产品接口中声明的业务方法。
具体应用举例:

抽象工厂:
/** * 字体颜色工厂接口,充当 抽象工厂 */ public interface ColourFactory { /** * 创建数字产品 * @return */ Digit createDigit(); /** * 创建字母产品 * @return */ Letter createLetter(); /** * 创建标记产品 * @return */ Mark createMark(); /** * 通过子类class获取当前类的子类 * @param clazz * @param <T> * @return * @throws Exception */ static <T extends ColourFactory> T getSubClass(Class<T> clazz) throws Exception { ColourFactory product = (ColourFactory) Class.forName(clazz.getName()).newInstance(); return (T) product; } }
具体工厂:
/** * 黑色工厂,充当具体工厂 */ public class BlackColourFactory implements ColourFactory { @Override public Digit createDigit(){ return new BlackDigit(); } @Override public Letter createLetter(){ return new BlackLetter(); } @Override public Mark createMark(){ return new BlackMark(); } } /** * 黑色工厂,充当具体工厂 */ public class RedColourFactory implements ColourFactory { @Override public Digit createDigit(){ return new RedDigit(); } @Override public Letter createLetter(){ return new RedLetter(); } @Override public Mark createMark(){ return new RedMark(); } }
抽象产品:
/** * 数字接口,充当抽象产品 */ public interface Digit { void display(); } /** * 字母抽象产品 */ public interface Letter { void display(); } /** * 符号接口,充当抽象产品 */ public interface Mark { void display(); }
具体产品:
/** * 黑色数字类,充当具体产品 */ public class BlackDigit implements Digit { @Override public void display(){ System.out.println("显示黑色数字"); } } /** * 黑色字母,充当具体产品 */ public class BlackLetter implements Letter { @Override public void display(){ System.out.println("显示黑色字母"); } } /** * 黑色符号类,充当具体产品 */ public class BlackMark implements Mark { @Override public void display(){ System.out.println("显示黑色符号"); } } /** * 红色数字,充当具体产品 */ public class RedDigit implements Digit { @Override public void display(){ System.out.println("显示红色数字"); } } /** * 红色字母,充当具体产品 */ public class RedLetter implements Letter { @Override public void display(){ System.out.println("显示红色字母"); } } /** * 红色符号类,充当具体产品 */ public class RedMark implements Mark { @Override public void display(){ System.out.println("显示红色符号"); } }
调用测试:
@Slf4j public class AbstractFactoryTest { @SneakyThrows public static void main(String args[]){ /* 使用抽象层定义 */ //抽象工厂 ColourFactory factory; //抽象数字产品 Digit dt; //抽象字母产品 Letter lt; //抽象符号产品 Mark mk; /* 指定具体工厂,生成具体产品 */ //指定具体工厂:黑色工厂 factory = ColourFactory.getSubClass(BlackColourFactory.class); //用指定工厂生产具体产品 dt = factory.createDigit(); lt = factory.createLetter(); mk = factory.createMark(); /* 使用具体产品*/ dt.display(); lt.display(); mk.display(); /*假如说,以后再想增加其他颜色产品,比如说绿色,只需要增加一个GreenColourFactory和三个产品类:GreenDit, GreenLetter, GreenMark 不会影响现有其他产品类和工厂,使用时直接在这里进行如下调用即可 factory = ColourFactory.getSubClass(GreenColourFactory.class); dt = factory.createDigit(); lt = factory.createLetter(); mk = factory.createMark(); dt.display(); lt.display(); mk.display();*/ } }
运行结果显示:

程序中封装一下,其他地方直接调用 dealBusiness () 方法即可:
/** * 抽象工厂 处理客户端 * @author wg */ @Component
@Data @Slf4j public class XxxAbstractFactoryClient { /** * 抽象工厂 */ ColourFactory factory; /** * 抽象数字产品 */ Digit digit; /** * 抽象字母产品 */ Letter letter; /** * 抽象符号产品 */ Mark mark; @PostConstruct public void init() { try { /* 指定产品具体工厂,进而初始化产品 */ initFactory (BlackColourFactory.class); } catch (Exception e) { log.error(e.getMessage(), e); } } public void dealBusiness () { /* 使用具体产品*/ digit.display(); letter.display(); mark.display(); } private void initFactory (Class clazz) throws Exception { // 指定具体工厂 factory = ColourFactory.getSubClass(clazz); digit = factory.createDigit(); letter = factory.createLetter(); mark = factory.createMark(); } }
浙公网安备 33010602011771号