工厂方法模式
介绍
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
优缺点
优点:
工厂方法模式就很好的减轻了工厂类的负担,把某一类/某一种东西交由一个工厂生产;(对应简单工厂的缺点1)
同时增加某一类”东西“并不需要修改工厂类,只需要添加生产这类”东西“的工厂即可,使得工厂类符合开放-封闭原则。
缺点:
对于某些可以形成产品族(一组产品)的情况处理比较复杂
工厂方法示例
package com.wang.i_factorymethod.a;
// 针对简单工厂中的问题,
// 作者修改代码如下:使用工厂方法设计模式。
//抽象产品
interface Food {
void eat();
}
// 具体产品
class Hamburger implements Food {
public void eat() {
System.out.println("吃汉堡包");
}
}
class RiceNoodle implements Food {
public void eat() {
System.out.println("吃过桥米线");
}
}
interface FoodFactory {
Food getFood();
}
class HamburgerFactory implements FoodFactory {
public Food getFood() {
return new Hamburger();
}
}
class RiceNoodleFactory implements FoodFactory {
public Food getFood() {
return new RiceNoodle();
}
}
// ===============================================================
class LP implements Food {
public void eat() {
System.out.println("三秦套餐 - 吃凉皮");
}
}
class LPFactory implements FoodFactory {
public Food getFood() {
return new LP();
}
}
class Bussiness{
public static void taste(FoodFactory ff){
Food f = ff.getFood();
f.eat();
Food f2 = ff.getFood();
f2.eat();
Food f3 = ff.getFood();
f3.eat();
}
}
public class AppTest {
public static void main(String[] args) {
Bussiness.taste(new HamburgerFactory());
Bussiness.taste(new LPFactory());
}
}
接口要趋向于稳定, 设计模式中的接口,不单指interface,只要是下层给上层暴露的方法,都叫接口。一个公共方法,或者类,只要暴露出去,都是接口。
简单工厂 优点: 1、把具体产品的类型,从客户端解耦出来 2、服务器端,如果修改了具体产品的类名,客户端也不知道,这符合了面向接口编程思想。
工厂方法
优点:
1、仍然具有简单工厂的优点,服务器端修改了具体产品的类名,客户端不知道
2、当客户端要扩展一个新的产品时,不需要修改作者原来的代码,只是要扩展一个新的工厂而已。
杠点:
1、我们已经知道,简单工厂也好,工厂方法也好,都有一个优点,就是服务器端的具体产品类名变化后,客户端不知道。
但是,反观我们的代码,客户端仍然依赖于具体的工厂的类名。此时,如果服务器端修改了具体工厂的类名,那么客户端也要同时修改。
感觉折腾了一番,又回到了原点。
解释:
作为工厂的名字,是被视为接口。作者有责任也有义务保证工厂名字的稳定,也就是说,虽然客户端依然依赖于具体类名,但是在IT界内,所有工厂名称都是趋向于稳定的(并不是100%)。至少工厂类的名字要比具体产品的名字稳定。
2、既然产品是我们自己客户端扩展出来的,那么为什么不直接自己实例化?毕竟这个扩展出来的产品LP,我们自己就是作者,我们怎么修改类名自己都能把控。
为什么要为自己制作的产品做工厂。
解释:
因为,作者在开发功能时,不仅仅会开发一些抽象产品,具体产品,对应的工厂,还会配套有产品及工厂的框架。
3、现在制作出LPFactory,是为了把LPFactory传入给Bussiness.taste()方法,所以必须制定这个LPFactory,那么为什么不一开始就让Bussiness.taste方法直接接收Food参数呢?而不是现在的FoodFactory作为参数。
解释:
Bussiness.taste(new Hamburger()); 会与具体产品发生耦合,而而接收LPFactory,也会发生耦合。原因回归杠点1.
缺点:
如果有多个产品等级,那么工厂类的数量就会爆炸式增长。(食物Food,饮料Drink 两个产品等级。)如何解决?采用抽象工厂解决。
UML类图