简介
抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式将一组具有共同主题的单个工厂封装起来,它提供接口用于创建相关或依赖对象的家族,而不需要指定具体的类。
抽象工厂模式包含以下几个核心角色:
- 抽象工厂(Abstract Factory):声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体产品对象的实例。
- 抽象产品(Abstract Product):定义了一组产品对象的共同接口或抽象类,描述了产品对象的公共方法。
- 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
适用场景:
- 当一个系统需要独立于它的产品的创建、组合和表示时
- 当一个系统需要多个系列的产品族,而不希望依赖于具体类时
优点:
- 将客户端与具体的产品类解耦,使得客户端可以轻松切换不同的具体工厂
- 符合开闭原则,易于扩展,添加新的产品族和产品等级结构
缺点:
- 增加新的产品族和产品等级结构比较复杂,需要修改抽象工厂和所有具体工厂的接口
- 对于新添加的产品族,需要修改所有的具体工厂类,这增加了系统的复杂度
示例代码
Go
本例使用RDB
和XML
存储订单信息,抽象工厂分别能生成相关的著订单信息和订单详情信息。如果业务逻辑中需要替换其他存储方式,使用的时候只需要改动工厂函数相关的类即可。
abstractfactory/demo.go
package abstractfactory // OrderMainDAO 为订单主记录, 抽象产品 type OrderMainDAO interface { SaveOrderMain() string } // OrderDetailDAO 为订单详情记录, 抽象产品 type OrderDetailDAO interface { SaveOrderDetail() string } // DAOFactory DAO 抽象工厂接口 type DAOFactory interface { CreateOrderMainDAO() OrderMainDAO CreateOrderDetailDAO() OrderDetailDAO } // RDBMainDAO 关系型数据库的OrderMainDAO实现, 具体产品 type RDBMainDAO struct{} func (*RDBMainDAO) SaveOrderMain() string { return "RDB main save" } // RDBDetailDAO 是关系型数据库的OrderDetailDAO实现, 具体产品 type RDBDetailDAO struct{} func (*RDBDetailDAO) SaveOrderDetail() string { return "RDB detail save" } // RDBDAOFactory 是RDB抽象工厂实现, 具体工厂类 type RDBDAOFactory struct{} func (*RDBDAOFactory) CreateOrderMainDAO() OrderMainDAO { return &RDBMainDAO{} } func (*RDBDAOFactory) CreateOrderDetailDAO() OrderDetailDAO { return &RDBDetailDAO{} } // XMLMainDAO 是XML存储的OrderMainDAO 实现, 具体产品 type XMLMainDAO struct{} func (*XMLMainDAO) SaveOrderMain() string { return "XML main save" } // XMLDetailDAO 是XML存储的OrderDetailDAO实现, 具体产品 type XMLDetailDAO struct{} func (*XMLDetailDAO) SaveOrderDetail() string { return "XML detail save" } // XMLDAOFactory 是XML抽象工厂实现, 具体工厂类 type XMLDAOFactory struct{} func (*XMLDAOFactory) CreateOrderMainDAO() OrderMainDAO { return &XMLMainDAO{} } func (*XMLDAOFactory) CreateOrderDetailDAO() OrderDetailDAO { return &XMLDetailDAO{} }
- 单元测试:
abstractfactory/demo_test.go
package abstractfactory import ( "testing" ) func TestDAO(t *testing.T) { var factory DAOFactory factory = &RDBDAOFactory{} if factory.CreateOrderMainDAO().SaveOrderMain() != "RDB main save" { t.Fatal("error with abstract factory pattern. RDB Main DAO") } if factory.CreateOrderDetailDAO().SaveOrderDetail() != "RDB detail save" { t.Fatal("error with abstract factory pattern. RDB Detail DAO") } factory = &XMLDAOFactory{} if factory.CreateOrderMainDAO().SaveOrderMain() != "XML main save" { t.Fatal("error with abstract factory pattern. XML Main DAO") } if factory.CreateOrderDetailDAO().SaveOrderDetail() != "XML detail save" { t.Fatal("error with abstract factory pattern. XML Detail DAO") } }
Python
from abc import ABC, abstractmethod class OrderMainDAO(ABC): """订单主要记录, 抽象产品类 """ @abstractmethod def save_order_main(self) -> str: pass class OrderDetailDAO(ABC): """订单详情, 抽象产品类 """ @abstractmethod def save_order_detail(self) -> str: pass class DAOFactory(ABC): """抽象工厂类 """ @abstractmethod def create_order_main_dao(self): pass def create_order_detail_dao(self): pass class RDBMainDAO(OrderMainDAO): """RDB存储订单主要记录, 具体产品类, 实现抽象产品类OrderMainDAO """ def save_order_main(self) -> str: return "RDB Main DAO" class RDBDetailDAO(OrderDetailDAO): """RDB存储订单详情, 具体产品类, 实现抽象产品类OrderDetailDAO """ def save_order_detail(self) -> str: return "RDB Detail DAO" class RDBDAOFactory(DAOFactory): """RDB存储, 具体工厂类, 实现抽象工厂类DAOFactory """ def create_order_main_dao(self): return RDBMainDAO() def create_order_detail_dao(self): return RDBDetailDAO() class XMLMainDAO(OrderMainDAO): """XML存储订单主要记录, 具体产品类, 实现抽象产品OrderMainDAO """ def save_order_main(self): return "XML Main DAO" class XMLDetailDAO(OrderDetailDAO): """XML存储订单详情, 具体产品类, 实现抽象产品 OrderDetailDAO """ def save_order_detail(self): return "XML Detail DAO" class XMLDAOFactory(DAOFactory): """XML存储, 实现抽象工厂类DAOFactory """ def create_order_main_dao(self): return XMLMainDAO() def create_order_detail_dao(self): return XMLDetailDAO() if __name__ == "__main__": factory = RDBDAOFactory() print(factory.create_order_main_dao().save_order_main()) print(factory.create_order_detail_dao().save_order_detail()) factory = XMLDAOFactory() print(factory.create_order_main_dao().save_order_main()) print(factory.create_order_detail_dao().save_order_detail())