设计模式 工厂模式
1.简单工厂模式
更像是一种编程习惯
优点:
- 将类的创建封装在工厂里,统一管理要创建实例的类,统一管理创建逻辑。
- 屏蔽了客户端的创建逻辑,解耦了客户端对具体类的依赖。
缺点:
- 添加新的实例类需要修改工厂类,违背了开闭原则
- 工厂类集中了所有实例的创建逻辑,一旦出现问题,整个系统受到影响
- 使用静态工厂方法,不能被继承重写,造成工厂角色不能形成基于继承的等级结构。
应用场景:
- 客户端不关心对象创建逻辑
- 工厂负责创建的对象较少
2.工厂方法模式
定义:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
总结:
- 优点
符合开闭原则,增加新产品只需增加新产品及其对应工厂。(修改判断逻辑)
符合单一职责原则,每个具体工厂类只负责创建对应的产品。(简单工厂通过判断逻辑生产对象实例)
将创建对象的代码封装起来。实例化具体类的代码,很可能在以后经常需要变化。“工厂”的技巧,可以封装实例化的行为。 将创建对象的代码集中在一个对象或者方法中,可以避免代码的重复,方便以后维护。这也意味着客户在实例化对象时,只会依赖于接口,而不是具体类。这可以帮助我们针对接口编程,而不是针对实现编程。让代码更具有弹性,应对未来的扩展。
没有像简单工厂中switch 违反开闭原则。 - 缺点
添加新产品需要成对增加类,提升系统复杂度;虽然在工厂方法内对修改关闭了,但是对于使用工厂的类来说,更换另一种产品是,仍需要修改为具体的工厂类。
实例:
.NET 类库中也有很多实现了工厂方法的类,例如Asp.net中,处理程序对象是具体用来处理请求的对象,当我们请求一个*.aspx的文件时,此时会映射到System.Web.UI.PageHandlerFactory类上进行处理,而对*.ashx的请求将映射到System.Web.UI.SimpleHandlerFactory类中(这两个类都是继承于IHttpHandlerFactory接口的),关于这点说明我们可以在“C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Web.Config”文件中找到相关定义,具体定义如下:
<httpHandlers> <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True" /> <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True" /> <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True" /> </httpHandlers>
下面我们就具体看下工厂方法模式在Asp.net中是如何实现的,如果对一个Index.aspx页面发出请求时,将会调用PageHandlerFactory中GetHandler方法来创建一个Index.aspx对象,它们之间的类图关系如下:
3.抽象工厂模式
定义
抽象工厂模式提供一个接口,用于创建相关或以来对象的家族,而不需要明确指定具体类。
抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道实际产出的具体产品。这样客户就从具体产品中解耦了(NYPizzaStore只知道AbstractProduct不知道具体Product)。
优点
减少客户端和具体产品的依赖,降低耦合,有利于维护和扩展
符合开闭原则
符合单一职责原则
缺点
很难支持添加新产品,此时需要修改抽象工厂的接口,涉及的子类会很多,违背开闭原则。
要点
1)所有工厂都是用来封装对象的创建的,减少应用程序和具体类之间的依赖促进松耦合。
2)简单工厂,虽然不是真正的设计模式,但仍不失为一个简单方法,可以将客户程序从具体类解耦。
3)工厂方法使用继承,把对象的创建委托给子类,子类实现工厂方法来创建对象。
4)抽象工厂使用对象组合,对象的创建被实现在工厂接口所暴露出来的方法中。
5)工厂方法允许类将实例化延迟到子类。
6)抽象工厂创建相关的对象家族,而不需要依赖他们的具体类。
7)依赖倒置原则,指导我们避免依赖具体类型,而要尽量以来抽象。
8)工厂帮助我们针对抽象编程,而不针对具体编程。
--
先分析问题,将当前需求的类划分清楚,然后设计自己的Factory
目的是将使用者和具体被使用的对象解耦。
当每个对象的创建逻辑都比较简单的时候,推荐使用简单工厂模式,将多个对象的创建逻辑放到一个工厂类中。
当每个对象的创建逻辑都比较复杂的时候,为了避免设计一个过于庞大的简单工厂类,推荐使用工厂方法模式,将创建逻辑拆分得更细,每个对象的创建逻辑独立到各自的工厂类中。