抽象工厂
Introduction
抽象工厂模式,提供一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
实现抽象工作模式所需要的组件,主要部分:
- 抽象工厂/抽象产品
- 具体工厂 1/具体产品 1
- 具体工厂 2/具体产品 2
- ... 在客户端根据不同的配置选择不同的工厂,例如根据配置的数据库类型的不同选择使用 Access 数据库仓储的工厂还是使用 SqlServer 数据库的仓储工厂
IDbFactory factory = new AccessFactory();
var userRepo = factory.CreateUserRepo();
userRepo.Insert(null);
var departmentRepo = factory.CreateDepartmentRepo();
factory = new SqlServerFactory();
userRepo = factory.CreateUserRepo();
userRepo.Insert(null);
工厂方法和抽象工厂的区别
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类
抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类 区别在于产品,如果产品单一,最合适用工厂模式,但是如果有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
再通俗深化理解下:工厂模式针对的是一个产品等级结构 ,抽象工厂模式针对的是面向多个产品等级结构的。
抽象工厂关键在于产品之间的抽象关系,所以一般至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品。
抽象工厂更像一个复杂版本的策略模式,策略模式通过更换策略来改变处理方式或者结果;而抽象工厂的客户端,通过更换工厂而改变结果。
工厂方法目的是生产产品,所以能看到产品,而且还要使用产品。当然,如果产品在创建者内部使用,那么工厂方法就是为了完善创建者,从而可以使用创建者。另外创建者本身是不能更换所生产产品的。
抽象工厂的工厂是类;工厂方法的工厂是方法。抽象工厂的工厂类就做一件事情生产产品。生产的产品给客户端使用,绝不给自己用。工厂方法生产产品,可以给系统用,可以给客户端用,也可以自己这个类使用。自己这个类除了这个工厂方法外,还可以有其他功能性的方法。
适用场景
- 系统需要一系列相关或相互依赖的对象,而客户端不希望知道它们的具体实现。
- 系统需要同时使用多个不同的产品族,但是每次只能使用其中一种产品族。
- 系统需要保证一组产品的一致性,即只能使用同一个工厂生产出来的产品。
- 系统需要提供一个产品的类库,而且所有的产品都可以按照同样的接口进行调用。
优点
- 实现了客户端与具体实现的分离,客户端只需要知道抽象工厂和抽象产品的接口,不需要关心具体实现,从而降低了耦合度。
- 抽象工厂模式可以确保客户端使用的是同一系列的产品,保证了产品的一致性。
- 容易扩展新的产品系列,只需要增加相应的具体工厂和产品类即可,无需修改原有代码。
- 符合开闭原则,增加新的产品族不需要修改原有的代码,只需要增加新的具体工厂和产品类即可。
缺点
- 抽象工厂模式的扩展性有限,产品族的扩展比较困难,需要修改抽象工厂的接口,这样会对原有系统造成一定的影响。
- 增加新的产品等级结构比较困难,需要修改所有的具体工厂类,这样会对原有系统造成一定的影响。
- 增加新的产品族和产品等级结构时,需要增加大量的具体类,增加了系统的复杂度和维护难度。
- 抽象工厂模式的使用条件比较苛刻,只有当需要一系列相关或相互依赖的对象时才适合使用抽象工厂模式。
总结
抽象工厂模式是工厂方法模式的扩展,用于生产一系列相关或相互依赖的对象。抽象工厂模式可以保证客户端使用的是同一系列的产品,从而保证了产品的一致性。但是抽象工厂模式的扩展性有限,增加新的产品族和产品等级结构比较困难,需要修改抽象工厂的接口或所有的具体工厂类。在使用抽象工厂模式时,需要考虑系统的可扩展性和维护难度,只有当需要一系列相关或相互依赖的对象时才适合使用抽象工厂模式。