创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化托给另一个对象。随着系统演化得越来越依赖于对象复合而不是类继承时,创建型模式变得更为重要。接下来,我们马上进入对第一个创建型模式的介绍——工厂方法模式。
软件系统中,经常面临着“某个对象”的创建问题。由于用户需求的改变,该对象的具体实现时常面临着剧烈的变化,但是其所固有的接口却是比较稳定的,如何来应对这种需求上变化?通过封闭机制来隔离这个“易变对象”的变化点,使系统中“依赖于该对象的对象”不会随着需求的改变而改变,保持系统一定的稳定性和健壮性。这就是工厂方法善于解决的方面呢。
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类实例化延迟到其子类。
抽象工厂(creator)角色:是工厂方法模式的核心,任何通过该模式创建对象的具体工厂类都须实现该接口 具体工厂(ConcreteCreator)角色:实现了抽象工厂类的具体工厂类,包含与应用程序相关的逻辑,被客户端调用以生成具体的产品对象。在上图中类BMWCreator和BENZCreator就是两个具体的工厂实现类,用于创建不同实现的Car对象 抽象产品(Product)角色:工厂方法所创建的对象的父类型,也就是具体产品对象的共同父类或者说是共同拥有的接口。在上图中,这个角色为Car 具体产品(ConcreteProduct)角色:实现了抽象产品接口的产品。每个具体产品与创建自己的具体工厂是一般来说是一一对应。上图中,BMW和BENZ就是两个具体的具体产品类
从上面代码中,我们可以很清楚地看到,工厂方法实现的一般做法。从客户端代码上来看,我们均是操作抽象类对象,这也是面向接口编程的核心。需要创建具体产品对象,只需要首先获取对应的产品工厂,再由其创建具体产品对象。在这里,我们可以看到:工厂方法模式实现时,客户端需要决定实例化哪一个具体工厂来创建特定的产品对象,对比简单工厂模式,工厂方法把内部逻辑判断转移到了客户端代码来进行,想要实例化新的产品对象,只需要修改客户端同时添加对应的具体工厂类,而不需要修改工厂类,符合了面向对象的“开闭原则“——对扩展开放,对修改关闭。而简单工厂模式的最大优点在于工厂类方法中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对客户端来说,除去了与具体产品的依赖,但是当添加新的产品时,就不得不修改工厂类逻辑,违背了”开闭原则“。
在实际的运用场景中,工厂方法应该是最被常用的模式之一呢。不仅因为此模式实现过程的简约,更是因为其实用性。应该说,在任何商业软件系统中都不乏工厂方法模式的身影,比如利用工厂方法模式切换各种数据库示例,由于主流的数据库几乎都支持增、删、改、查的功能(即crud),换句话来说就是各数据库所支持的接口都是相同的,但是不同的数据库有不同的实现方式,通过工厂方法模式,我们就可以很方便地动态创建各种接口相同但是实现不同的数据库操作类对象。具体实现的方式与示例代码的实现框架一致,这里就不重复举例呢。
工厂方法模式的本质是:延迟到子类来选择实现。工厂方法很好地体现了开闭原则和依赖倒置原则。”开闭原则“告诉我们”对扩展开放,对修改关闭“,在工厂方法模式中,我当我们需要添加新的产品对象时,只需要根据产品接口实现新的产品对象以及根据抽象的工厂方法接口来实现新的具体工厂,然后通过相同的逻辑利用对应的具体的工厂方法来创建该新产品对象。”依赖倒置原则“告诉我们的”要依赖抽象,不要依赖于具体类“,简单地说就是让高层组件依赖于低层组件,而且不管高层组合还是低层组件都应该依赖于抽象,而不是具体的实现,在工厂方法模式中,我们可以看到,不管是具体工厂类还是具体产品类都是根据统一的接口(或者抽象)来完成各种不同实现,而且客户端也只需要与相应的抽象类找交道即可。好呢,工厂方法模式的讲解就到这吧,相较而言,工厂方法模式的实现比较简单,我们大家需要理解的是其本质和适应场景。下一篇,我们将继续介绍工厂方式模式的同胞兄弟——抽象工厂方法模式,敬请期待!
参考资料:
程杰著《大话设计模式》一书陈臣等著《研磨设计模式》一书GOF著《设计模式》一书Terrylee .Net设计模式系列文章吕震宇老师 设计模式系列文章
转载于:https://www.cnblogs.com/JackyTecblog/archive/2012/09/16/2687811.html
