工厂方法和抽象工厂设计模式

JAVA ginotang 1089℃ 0评论

工厂方法设计模式

工厂方法的目的是为了让创建对象的过程从客户端(使用该对象的代码)解耦出来。也就是说,工厂方法解决的问题是如何优雅地创建对象。当你的程序可能出现以下情况时,就应该考虑使用工厂方法。

  • 将要创建的对象拥有一个共同的父类
  • 这个对象的类型是在运行时动态决定的

工厂方法设计模式这样定义:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

这句话什么意思?定义了创建对象的接口这一句可能会有点迷惑。其实这个接口并非一定就是要使用java的interface声明的类,它可以是一个类,接口只是父类的泛指。简单来说,就是父类通过暴露一个抽象方法,子类按照自己的方式去实现这个方法即可。考虑一个问题:在一个可以更换武器的游戏之中,应该怎样设计才能优雅地创建这些武器对象。假设武器有:木剑,石剑,AK47, 霰弹枪。

粗暴的实现方法

假设我们把这些武器类定义为WoodSwordRockSwordAK47ShotGun,然后我们定义了一个Character类来使用这些武器。Character内部定义了一个attack方法,这个attack方法单纯调用了武器的attack方法。

然而这个方法问题很明显,它首先违反了面向对象编程中对修改关闭的原则,其次,这样的代码根本就没有办法复用,所以,这是一个很糟糕的实现。

使用工厂方法改造

这些武器类中,可以看出只有枪和剑,现在我们通过简单的抽象把上面糟糕的代码进行重构。先说说重构的思路:定义一个WeaponFactory父类,该类定义了一个抽象方法createWeapon,用于返回一个武器装置,可以通过继承这个父类创建不同的武器。

代码清爽了不少,更重要的是,这样的代码更加灵活,复用性也更高。接着我们来看一看SwordWeaponFactory的代码:

现在再反过来看一看一开头定义的这句话:工厂方法让类把实例化推迟到子类。现在,我们应该明白这句话的意思了吧,也许我们应该说,真正决定实例化哪一个类的应该是游戏的玩家。

就是这么简单,没错,这就是工厂方法。使用工厂方法只需要三个步骤:

  • 定义一个父类,并开放一个方法让子类实现。
  • 创建该父类的子类。
  • 客户端通过该子类创建对象

 抽象工厂设计模式

抽象工厂模式和工厂方法有相似的地方,首先它们都是用来创建对象的设计模式,其次,它们都是通过父类开放公共方法的方式来实现。不同的是,抽象工厂模式创建的是一系列相关的对象,而工厂方法只是创建一个对象,这也是它们主要的不同。

抽象工厂模式的定义:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

很官方的定义,咋一看似乎并不那么直观。但是很明确的一点是,它用来创建对象的家族,即多个对象,这多个对象共同组成一个产品

抽象工厂举例

一个简单的例子,每一台电脑都是由多个产品组成的,例如cpu,内存,主板,电源,机箱。那么,我们就可以把这些东西抽象到一个接口之中,子类只要实现这个接口,就能生产出一台可运作的电脑,但父类可以不管它们的具体实现。

抽象工厂的UML关系图如下:

父类只提供创建电脑的接口,具体如何去生产完全由子类自己去决定:用什么品牌的内存、主板、电源、机箱、CPU。现在先看看项目中用到的类:

解说一下执行流程:顾客来到电脑商店说:我要订购一台dell的电脑,然后,店主就拿来一台电脑。至于电脑的装配过程,顾客不需要知道,这些东西都封装到了ComputerStore中。代码演示:

ComputerStore中的代码是这样的:

可以看到,里面的ComputerFactory就是一个抽象工厂,这个类封装了如何安装电脑的规则。工厂代码如下:

就拿华硕电脑工厂来举例,华硕工厂实现了ComputerFactory

代码里面的每一个组件,比如CPU都可以使用一个工厂方法来封装,这里为了简单起见,只使用了一个setPartsType方法来模拟

来到这里,基本就可以解释什么是抽象工厂了。每一个电脑组件就是相互依赖的对象,它们共同组成一台电脑。电脑的组装规规则都定义在父类ComputerFactory中。

抽象工厂的问题:如果以后接口更新,例如添加其他部件,那么子类也要一并更改。毕竟,子类的实现依赖于父类。

总结

工厂方法和抽象工厂的相同点:

  • 它们都是用来创建对象,目的是为了是创建对象的过程从客户端解耦出来,实现了松耦合。
  • 对象的类型是运行时动态决定的

不同点:

工厂方法创建的是一个对象。

抽象工厂创建的是多个对象,且这些对象之间具有一定的依赖关系。或者说它们共同构成另一个完整的对象。

完整代码下载:https://github.com/whathegeek/abstractdesignpattern

转载请注明:Pure nonsense » 工厂方法和抽象工厂设计模式

喜欢 (0)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x