设计模式之工厂模式
工厂模式
一、简单工厂
简单工厂的意图很简单,就是当用户想要一个产品的时候,可以直接从工厂里把产品拿出来,而不需要自己new一个。
首先创建一个Car类:
1 | package factory; |
然后在main函数里开车,启动,wuwuwu…
1 | package factory; |
但是现在忽然想要开飞机,最简单的想法是再建立一个飞机类,飞机飞呀飞,xiuxiuxiu…
1 | package factory; |
更改main函数的代码即可…略…
However,此时我又想要开火车,这时候又要改变main代码,很麻烦,有没有比较好的方法呢?
所以创建一个Moveable的接口,里面有一个方法叫go(),然后让car、plane等交通工具类都去implement这个接口
1 | public interface Moveable { |
这样在main里就可以直接使用了:
1 | package factory; |
好,通过上述代码实现了随意定制交通工具了,但如果想要任意定制这个交通工具的生产过程呢?我们把生产新的交通工具的过程,交给一个工厂,这个工厂有很多类型,先考虑简单工厂。
1 | package factory; |
然后在main函数里调用的时候,就不需要自己new一个交通工具出来了,直接交给VehicleFactory去做就行。
1 | public class Main { |
这种方式很简单,但是可扩展性很差,因为每次想要新添加一个交通工具,都需要更改工厂代码。不符合开闭原则。那么干脆对每一种商品都构建一种工厂吧,这样就引入了第二种——工厂方法。
二、工厂方法
用来生产同一等级结构中的固定产品,支持增加任意产品,不需要覆盖原有代码。简而言之就是每一种Vehicle都有一个工厂。
首先建立一个接口VehicleFactory
1 | public interface VehicleFactory { |
然后建立每一种Vehicle的工厂,举个例子,比如CarFactory
1 | public class CarFactory implements VehicleFactory { |
(其余代码略)
这样每次使用的时候只需要在main里new一个对应的工厂就可以了
1 | Car c = new CarFactory().getVehicle(); |
三、抽象工厂
有一个超级工厂,这个超级工厂是用来生产工厂的工厂(好绕,感觉像在说绕口令QAQ)
直接看例子吧
这是一个抽象的超级工厂,可以看到里面不仅有创建食物,也能创建交通工具,还能创建武器(也就是抽象工厂里是抽象产品)
1 | public abstract class AbstractFactory { |
然后每一种类别又有自己的工厂,比如modenFactory,就是可以创建现代世界的食物、交通工具、武器(这是具体工厂,具体工厂里生产具体产品)
1 | public class ModernFactory extends AbstractFactory{ |
(Bread、Car、AK47类就是具体产品类,代码略)
比如我们的magicFactory,就是魔法世界的食物、交通工具和武器
1 | public class MagicFactory extends AbstractFactory{ |
下面是Main的示例:
1 | public class Main { |
简而言之就是一个超级工厂,然后超级工厂下面有大类的工厂(具体工厂),每个大类的工厂可以生产自己类别独有的商品,然后同一类具体的产品均有一个共同的interface需要实现。
抽象工厂模式包含以下几个核心角色:
- 抽象工厂(Abstract Factory):声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责创建具体产品对象的实例。
- 抽象产品(Abstract Product):定义了一组产品对象的共同接口或抽象类,描述了产品对象的公共方法。
- 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
当超级工厂里的具体工厂的类别只有一个时,其实就退化成了简单工厂。同样的,这种方式和简单工厂一样不满足开闭原则。