https://github.com/Wasabi1234...git
Collection 接口就至关于 VideoFactory
至关于各类具体的工厂,如 JavaVideoFactory
Itr 就是具体产品 JavaVideogithub
返回值是一个抽象类,必有一子类实现其,看一下
这其中URLStreamHandler就至关于各类抽象产品,而其实现类即各类具体的产品
URLStreamHandlerFactory就至关于 VideoFactory
而以下 Factory 就至关于如 JavaVideoFactory/PythonVideoFactory数据库
对造人过程进行分析,该过程涉及三个对象:女娲、八卦炉、三种不一样肤色的人segmentfault
Client
表示全部人种定义完毕,下一步就是定义一个八卦炉,而后烧制人类设计模式
最可能给八卦炉下达什么样的生产命令呢?
应该是给我生产出一个黄色人种(YellowHuman类)
而不会是给我生产一个会走、会跑、会说话、皮肤是黄色的人种
由于这样的命令增长了交流的成本,做为一个生产的管理者,只要知道生产什么就能够了,而不须要事物的具体信息
在这里采用了泛型,经过定义泛型对createHuman的输入参数产生两层限制
● 必须是Class类型
● 必须是Human的实现类
其中的T
表示,只要实现了Human接口的类均可以做为参数缓存
只有一个八卦炉,其实现生产人类的方法服务器
人种有了,八卦炉也有了,剩下的工做就是女娲采集黄土,而后命令八卦炉开始生产网络
人种有了,八卦炉有了,负责生产的女娲也有了
运行一下,结果以下所示
以上就是工厂方法模式框架
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses
定义一个用于建立对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类ide
在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象建立类,也就是抽象工厂,具体如何建立产品类是由具体的实现工厂ConcreteCreator完成的。工厂方法模式的变种较多,咱们来看一个比较实用的通用源码。
具体的产品类能够有多个,都继承于抽象产品类
负责定义产品对象的产生
具体如何产生一个产品的对象,是由具体的工厂类实现的
该通用代码是一个比较实用、易扩展的框架,读者能够根据实际项目须要进行扩展
一个对象建立是有条件约束的,如一个调用者须要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就能够了,不用知道建立对象的艰辛过程,下降模块间的耦合
在增长产品类的状况下,只要适当地修改具体的工厂类或扩展一个工厂类,就能够完成“拥抱变化”
例如在咱们的例子中,须要增长一个棕色人种,则只须要增长一个BrownHuman类,工厂类不用任何修改就可完成系统扩展。
这一特色很是重要,产品类的实现如何变化,调用者都不须要关心,它只须要关心产品的接口,只要接口保持不变,系统中的上层模块就不要发生变化
由于产品类的实例化工做是由工厂类负责的,一个产品对象具体由哪个产品生成是由工厂类决定的
在数据库开发中,你们应该可以深入体会到工厂方法模式的好处:若是使用JDBC链接数据库,数据库从MySQL切换到Oracle,须要改动的地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其余的都不须要修改,这是工厂方法模式灵活性的一个直接案例。
高层模块值须要知道产品的抽象类,其余的实现类都不用关心
符合迪米特法则,我不须要的就不要去交流
也符合依赖倒置原则,只依赖产品类的抽象
固然也符合里氏替换原则,使用产品子类替换产品父类,没问题!
在全部须要生成对象的地方均可以使用,可是须要慎重地考虑是否要增长一个工厂类进行管理,增长代码的复杂度
万物皆对象,那万物也就皆产品类
例如须要设计一个链接邮件服务器的框架,有三种网络协议可供选择:POP三、IMAP、HTTP
咱们就能够把这三种链接方法做为产品类,定义一个接口如IConnectMail
而后定义对邮件的操做方法
用不一样的方法实现三个具体的产品类(也就是链接方式)
再定义一个工厂方法,按照不一样的传入条件,选择不一样的链接方式
如此设计,能够作到完美的扩展,如某些邮件服务器提供了WebService接口,很好,咱们只要增长一个产品类就能够了
例如经过WebService与一个非Java的项目交互,虽然WebService号称是能够作到异构系统的同构化,可是在实际的开发中,仍是会碰到不少问题,如类型问题、WSDL文件的支持问题,等等。从WSDL中产生的对象都认为是一个产品,而后由一个具体的工厂类进行管理,减小与外围系统的耦合。
例如,测试一个类A,就须要把与类A有关联关系的类B也同时产生出来,咱们可使用工厂方法模式把类B虚拟出来,避免类A与类B的耦合。目前因为JMock和EasyMock的诞生,该使用场景已经弱化了,读者能够在遇到此种状况时直接考虑使用JMock或EasyMock
工厂方法模式有不少扩展,并且与其余模式结合使用威力更大,下面将介绍4种扩展。
咱们这样考虑一个问题:一个模块仅须要一个工厂类,没有必要把它产生出来,使用静态的方法就能够了,根据这一要求,咱们把上例中的AbstarctHumanFactory
修改一下
咱们在类图中去掉了AbstractHumanFactory
抽象类,同时把createHuman
方法设置为静态类型,简化了类的建立过程,变动的源码仅仅是HumanFactory和NvWa类
HumanFactory类仅有两个地方发生变化
createHuman
前增长static关键字工厂类发生变化,也同时引发了调用者NvWa的变化
运行结果没有发生变化,可是咱们的类图变简单了,并且调用者也比较简单,该模式是工厂方法模式的弱化,由于简单,因此称为简单工厂模式
(Simple Factory Pattern),也叫作静态工厂模式
在实际项目中,采用该方法的案例仍是比较多的
工厂类的扩展比较困难,不符合开闭原则,但它仍然是一个很是实用的设计模式。
当咱们在作一个比较复杂的项目时,常常会遇到初始化一个对象很耗费精力的状况,全部的产品类都放到一个工厂方法中进行初始化会使代码结构不清晰
例如,一个产品类有5个具体实现,每一个实现类的初始化(不只仅是new,初始化包括new一个对象,并对对象设置必定的初始值)方法都不相同,若是写在一个工厂方法中,势必会致使该方法巨大无比,那该怎么办?
考虑到须要结构清晰,咱们就为每一个产品定义一个创造者,而后由调用者本身去选择与哪一个工厂方法关联
咱们仍是以女娲造人为例,每一个人种都有一个固定的八卦炉,分别造出黑色人种、白色人种、黄色人种
抽象方法中已经再也不须要传递相关参数了,由于每个具体的工厂都已经很是明确本身的职责:建立本身负责的产品类对象。
三个具体的建立工厂都很是简单,可是,若是一个系统比较复杂时工厂类也会相应地变复杂。
运行结果仍是相同
每个产品类都对应了一个建立类,好处就是建立类的职责清晰,并且结构简单,可是给可扩展性和可维护性带来了必定的影响。为何这么说呢?若是要扩展一个产品类,就须要创建一个相应的工厂类,这样就增长了扩展的难度。由于工厂类和产品类的数量相同,维护时须要考虑两个对象之间的关系。
固然,在复杂的应用中通常采用多工厂的方法,而后再增长一个协调类,避免调用者与各个子工厂交流,协调类的做用是封装子工厂类,对高层模块提供统一的访问接口。
单例模式的核心要求就是在内存中只有一个对象
,经过工厂方法模式也能够只在内存中生产一个对象
Singleton定义了一个private的无参构造函数,目的是不容许经过new的方式建立一个对象
Singleton保证不能经过正常的渠道创建一个对象
反射~
经过得到类构造器,而后设置private访问权限,生成一个对象,而后提供外部访问,保证内存中的对象惟一
以上经过工厂方法模式建立了一个单例对象,该框架能够继续扩展,在一个项目中能够产生一个单例构造器,全部须要产生单例的类都遵循必定的规则(构造方法是private),而后经过扩展该框架,只要输入一个类型就能够得到惟一的一个实例。
一个对象被消费完毕后,并不马上释放,工厂类保持其初始状态,等待再次被使用
延迟初始化是工厂方法模式的一个扩展应用
,变化出无穷的优秀设计,这也正是软件设计和开发的乐趣所在。
本文由博客一文多发平台 OpenWrite 发布!