一般情况,学习都是由浅入深,本人也不例外,就从最简单的模式开始吧。简单工厂模式(SimpleFactory)应该算是最简单的设计模式之一了,因为简单所以也成为平时应用比较多的模式之一。简单工厂模式属于创建型模式的一种,主要用于集中创建一个具有统一接口的对象。
简单工厂模式也叫静态工厂模式,顾名思意,简单工厂的核心就是这个简单工厂类啦,简单工厂类集中承担了对象的创建工作,根据不同的条件返回满足要求的特定对象的实例。这种方式避免了将对象的创建遍布客户端和业务代码之中,统一集中到简单工厂内,使得客户端和业务代码不必关心对象的创建,专注于业务逻辑的实现和对象的使用。
当然了,集中创建是其优点,同时也是其缺点所在。当创建条件变的繁多而复杂时,会导致简单工厂方法逐渐变得庞大臃肿,难于维护。同时,由于需要在简单工厂方法内对创建对象的条件进行判断,会使代码出现较多的if...else或者switch...case等条件语句,每当需求变动,增加一种对象或者需要改变创建条件时,就不得不修改简单工厂类,这也违背了开闭原则。
简单工厂模式的UML类图结构如下:
Client:客户端类,通过SimpleFactory对象获取并使用IProduct的实例对象
SimpleFactory:简单工厂类,提供一个或多个静态方法用于创建IProduct对象的实例
IProduct:产品对象的抽象接口,定义了一类产品
ProductA/ProductB:IProduct产品的具体实现类
在平时的工作中,一般在较小的项目,在其业务逻辑的需求变动不大的情况下,会使用简单工厂方法来完成创建诸如业务对象、持久化对象的工作。有时会在系统里使用多个简单工厂,每个简单工厂负责创建具有同一抽象接口的对象。这一点也是需要注意的,因为经常看到有的实现,不管三七二十一,任何类型的创建都放在一个简单工厂方法类里,一个类有上千行的代码,维护人员看的眼睛都花了,无形中加大了不少维护难度和成本。要保证这一点,需要在项目实施和维护时就形成一个规范约定(最好有相关的规范文档和开发手册),以降低此风险。
简单工厂方法的使用便捷,快速,实现简单,对于程序员的要求可以说没有任何门槛,所以在低成本的小型项目中还是比较实用的。
正好最近在重温太平洋战争(WITP),就拿这个游戏里生产战舰作为例子吧。场景定为海军要求船坞生成战舰用于战斗。这里海军就是客户端,船坞就是简单工厂,而战舰则是各种军舰的抽象。类图如下:
呵呵,战舰种类算是比较齐全了。下面看看具体的实现代码:
首先是军舰的抽象类WarShip.java
简单工厂方法类Shipyard.java
具体类型的军舰,这里只显示航空母舰和战列舰的代码(严格来说,航空母舰和传统意义的战舰是有一定区别的,之间都实现战舰接口是不太合适的,但是这里我们关注于模式的实现,就暂且忽略这一点啦,呵呵)。
航空母舰AircraftCarrier.java
战列舰Battleship.java
最后是客户端的海军Navy.java
这时如果我想增加军舰种类,比如护卫舰、潜艇等,只需要新增相关军舰类,并修改简单工厂类,让其认识这种军舰类型即可。客户端即可直接使用。同样,如果我想更换各种军舰的实现,也变的简单了,比如巡洋舰从普通的类型升级到核动力巡洋舰,只要实现NuclearCruisers类,并修改Shipyard,将原来的返回Cruisers替换成NuclearCruisers,那么海军得到的就是最新式的核动力巡洋舰了。无需再crtl+f到处寻找和修改每一处创建Cruisers的代码,这就是集中创建的好处了。
OK,简单工厂模式就这么多内容了,下面来个最终的总结
名称:简单工厂模式
优点:对象创建逻辑集中,便于统一修改,创建对象和使用对象解耦,各司其责(单一职责);简单实用,容易实现
缺点:业务逻辑和创建条件的复杂容易造成简单工厂类的膨胀,同时在增加产品对象和改动创建条件时需要修改简单工厂类,违背了开闭原则。
文中代码和类图下载点击 这里
---------- To be continue ----------