开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第20天,点击查看活动详情
抽象工厂模式
针对于工厂方法中存在的问题,当有多个产品簇时,工厂类会爆炸性的增长 如下反例所示
-
反例
/**
*
*/
//抽象产品 食物
interface Food{
void eat();
}
//具体产品 汉堡包
class Hamburger implements Food{
@Override
public void eat() {
System.out.println("吃汉堡包!");
}
}
//具体产品 米线
class RiceNoodle implements Food{
@Override
public void eat() {
System.out.println("吃米线");
}
}
//抽象产品工厂 食物工厂
interface FoodFactory{
public Food getFood();
}
//具体产品工厂 汉堡包工厂
class HamburgerFactory implements FoodFactory{
@Override
public Food getFood() {
return new Hamburger();
}
}
//具体产品工厂 米线工厂
class RiceNoodleFactory implements FoodFactory{
@Override
public Food getFood() {
return new RiceNoodle();
}
}
//抽象产品 饮料
interface Drink{
public void drink();
}
//具体产品 可乐
class Cola implements Drink{
@Override
public void drink() {
System.out.println("可口可乐,你值得拥有!");
}
}
//具体产品 缤纷
class IcePeak implements Drink{
@Override
public void drink() {
System.out.println("西安人从小就喝");
}
}
//抽象饮料工厂
interface DrinkFactory{
public Drink getDrink();
}
//具体饮料工厂 可乐工厂
class KolaFactory implements DrinkFactory{
@Override
public Drink getDrink() {
return new Cola();
}
}
//具体饮料工厂 缤纷工厂
class IcePeakFactory implements DrinkFactory{
@Override
public Drink getDrink() {
return new IcePeak();
}
}
-
正例
- 使用抽象工厂模式。
- 代码
//抽象产品 食物 interface Food{ void eat(); } //具体产品 汉堡包 class Hamburger implements Food{ @Override public void eat() { System.out.println("吃汉堡包!"); } } //具体产品 米线 class RiceNoodle implements Food{ @Override public void eat() { System.out.println("吃米线"); } } //抽象产品 饮料 interface Drink{ public void drink(); } //具体产品 可乐 class Cola implements Drink{ @Override public void drink() { System.out.println("可口可乐,你值得拥有!"); } } //具体产品 缤纷 class IcePeak implements Drink{ @Override public void drink() { System.out.println("西安人从小就喝"); } } //抽象产品工厂 工厂 interface Factory{ public Food getFood(); public Drink getDrink(); } class KFCFactory implements Factory{ @Override public Food getFood() { return new Hamburger(); } @Override public Drink getDrink() { return new Cola(); } } class SanQinFactory implements Factory{ @Override public Food getFood() { return new RiceNoodle(); } @Override public Drink getDrink() { return new IcePeak(); } }-
分析
-
优点
- 仍然有简单工厂,和工厂方法的优点。
- 扩展产品簇的时候(新增别的Food和Drink),不需要添加过多的工厂类。
-
缺点
- 当产品等级(新增SmalllFoold)发生变化,需要修改之前工厂代码 违反了
开闭原则
- 当产品等级(新增SmalllFoold)发生变化,需要修改之前工厂代码 违反了
-
结论
- 当产品等级比较固定时,建议采用抽象工厂。