1、简介
抽象工厂(Abstract Factory)模式是一种创建型设计模式,它提供了一种方法创建相关或依赖对象的家族,而不需要明确指定它们的具体类。
在抽象工厂模式中,有一个抽象工厂类,它负责创建一组相关或依赖的对象。它包含多个用于创建不同对象的方法,每个方法都返回一个抽象产品类型的对象。
具体工厂类是抽象工厂的子类,它实现了在抽象工厂中声明的方法。每个具体工厂类可以创建多个具体产品类的实例。
抽象产品是一个接口或抽象类,它声明了由具体产品实现的方法。
具体产品是实现了抽象产品接口的具体类,每个具体产品类都定义了一组具体的方法。
2、适用情况
抽象工厂模式适用的情况包括:
①当系统中有多个产品族,每个产品族中又包含多个产品时。
例如,在一个汽车生产系统中,可能有多种品牌的汽车,每种品牌又有多种车型。在这种情况下,可以使用抽象工厂模式来创建不同品牌的汽车。
②当系统需要提供一组产品,而这些产品是相关的,或者属于同一类别时。
例如,在一个家庭生活系统中,可能需要提供一组家电产品,如冰箱、洗衣机、空调等。在这种情况下,可以使用抽象工厂模式来创建这些家电产品。
3、优缺点
优点:
抽象工厂模式提供了一种方法创建相关或依赖对象的家族。
它允许客户端使用抽象接口来创建产品,而不需要知道实际产品的类名。
抽象工厂模式可以使系统具有更好的灵活性,因为可以轻松地替换具体工厂。
缺点:
抽象工厂模式增加了系统的复杂度
因为客户端需要知道所有的具体工厂类才能使用它们。
如果系统中涉及的产品族较多,或者每个产品族中的产品较多,那么就需要定义很多的具体工厂类,这会增加系统的复杂度。
4、代码实现
1. interface AbstractFactory { 2. //抽象工厂 3. AbstractProductA createProductA(); 4. AbstractProductB createProductB(); 5. } 6. 7. class ConcreteFactory1 implements AbstractFactory { 8. //具体工厂 9. @Override 10. public AbstractProductA createProductA() { 11. //具体产品 12. return new ConcreteProductA1(); 13. } 14. @Override 15. public AbstractProductB createProductB() { 16. return new ConcreteProductB1(); 17. } 18. } 19. 20. class ConcreteFactory2 implements AbstractFactory { 21. @Override 22. public AbstractProductA createProductA() { 23. return new ConcreteProductA2(); 24. } 25. @Override 26. public AbstractProductB createProductB() { 27. return new ConcreteProductB2(); 28. } 29. } 30. 31. interface AbstractProductA { 32. void methodA(); 33. } 34. 35. class ConcreteProductA1 implements AbstractProductA { 36. @Override 37. public void methodA() { 38. // 实现方法A 39. System.out.println("A1"); 40. 41. } 42. } 43. 44. class ConcreteProductA2 implements AbstractProductA { 45. @Override 46. public void methodA() { 47. // 实现方法A 48. System.out.println("A2"); 49. 50. } 51. } 52. 53. interface AbstractProductB { 54. void methodB(); 55. } 56. 57. class ConcreteProductB1 implements AbstractProductB { 58. @Override 59. public void methodB() { 60. // 实现方法B 61. System.out.println("B1"); 62. 63. } 64. } 65. 66. class ConcreteProductB2 implements AbstractProductB { 67. @Override 68. public void methodB() { 69. // 实现方法B 70. System.out.println("B2"); 71. 72. } 73. } 74. 75. public class test { 76. public static void main(String[] args) { 77. AbstractFactory factory = new ConcreteFactory1(); 78. AbstractProductA productA = factory.createProductA(); 79. AbstractProductB productB = factory.createProductB(); 80. productA.methodA(); 81. 82. } 83. }
定义了抽象工厂和抽象产品两个接口,然后使用具体工厂实现具体产品,如图所示,在客户端代码中,通过抽象工厂得到具体工厂、具体工厂创造具体产品的方式来创建产品
总的来说,抽象工厂模式是一种有用的设计模式,它可以解决多个产品族的创建问题,但是在使用时应该根据系统的具体情况进行选择。
5、应用场景
常见的抽象工厂模式的应用场景是创建数据库访问对象
例如,我们有一个系统需要连接到不同的数据库(Oracle, MySQL, SQL Server等),并执行不同的SQL语句。我们可以使用抽象工厂模式来实现这个功能。
首先定义抽象工厂接口DBConnectionFactory,其中定义了创建数据库连接和命令的抽象方法:
1. interface DBConnectionFactory { 2. DBConnection createDBConnection(); 3. DBCommand createDBCommand(); 4. }
然后为不同数据库创建具体的工厂类,例如 OracleDBConnectionFactory, MySqlDBConnectionFactory, SqlServerDBConnectionFactory,实现对应数据库连接和命令
1. class OracleDBConnectionFactory implements DBConnectionFactory { 2. public DBConnection createDBConnection() { 3. return new OracleDBConnection(); 4. } 5. public DBCommand createDBCommand() { 6. return new OracleDBCommand(); 7. } 8. } 9. class MySqlDBConnectionFactory implements DBConnectionFactory { 10. public DBConnection createDBConnection() { 11. return new MySqlDBConnection(); 12. } 13. public DBCommand createDBCommand() { 14. return new MySqlDBCommand(); 15. } 16. }
最后,在系统中只需要在运行时指定使用哪个工厂来创建数据库访问对象即可
1. DBConnectionFactory factory = getDBConnectionFactory(); 2. DBConnection conn = factory.createDBConnection(); 3. DBCommand cmd = factory.createDBCommand();
这样,当需要在不同数据库上运行系统时,只需要在 getDBConnectionFactory() 中返回不同的工厂实例即可创建不同数据库的访问对象。 这样就不需要在系统中做大量的if else判断,可以在类层次中使用继承来实现可拓展性和可维护性。