使用场景
- 在任何需要生成复杂对象的地方,都可以使用工厂模式。
- 工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
- 当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
- 有明确地计划,在不同条件下创建不同实例
注:对于简单对象,特别是只需要通过 new 就可以完成创建的对象,如果使用工厂模式,就需要引入一个工厂类,就只是增加系统的复杂度了。
优缺点
- 简化了调用者的代码复杂度
- 屏蔽产品的具体实现,调用者只关心产品的接口。
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
设计原理
将复杂的创建逻辑进行转移创建一个工厂类,定义一个用于获取对象的接口,通过使用这个公共的接口完成对实例的引用。让具体工厂决定如何实例化对象,且能使实例的实例化延时
- 创建对象时不会对客户端暴露创建逻辑
类图
简单工厂模式
工厂方法模式
角色
实现方式
简单工厂模式和工厂方法模式的区别
1、简单工厂模式中包含判断什么对象的逻辑,而工厂方法模式则需要调用者判断要实例化什么具体类型的工厂进而创建出想要的对象。当增加新类时,简单工厂模式需要修改工厂类,而工厂方法模式不需要,因此工厂方法模式遵守了开闭原则,而简单工厂模式没遵守。
2、简单工厂模式因为采用了静态方法,所以不利于继承,而工厂方法模式恰恰相反,需要利用到继承来从抽象工厂中派生出各种各样的具体工厂。
简单工厂模式
//严格来说,简单工厂违背开闭原则,不属于Gof23Mouse m1 = SimFactory.Create(1);Mouse m2 = SimFactory.Create(2);
工厂方法模式
Mouse mm1 = new HpMouseFactory().Create();Mouse mm2 = new DellMouseFactory().Create();//很好地符合了开放封闭原则(即对扩展开发,对修改封闭)
实际应用
.NET 中Encoding的UML图为:
特殊处理
Encoding即是对工厂模式的一种应用,有做了些许的扩展,当有稀有的编码传入时通过如下手段进行了处理。
switch (codepage){.......default:unicode = GetEncodingCodePage(codepage);if (unicode == null){unicode = GetEncodingRare(codepage); //当编码很少见时}break;......}
