前言
本程序改编自《Head First Design Patterns》(简称HF )中的关于Pizza的例子(可以在GitHub下载)。
图:HF 上的抽象工厂类图。Client位于图右上角。AbstractProductA的一个子类和AbstractProductB的一个子类,两个子类合在一起构成一个产品族,即 a family of products
HF 上面的例子的Client是一个抽象类,及其子类;然后又用了一个工厂方法模式,封装了new Client( )的过程。我觉得这样子没有必要,于是把书上的例子做了简化:把Client改成普通类;然后再用一个简单工厂封装new Client( )的过程。这样子丝毫不影响抽象工厂的精髓,反而还可以简化代码,突出重点。
PS. 实验楼网站里面的例子中,Client是一个普通类,没有用简单工厂或者工厂方法模式封装Client。我觉得这样子不好,因为这样直接把”Client的new的过程“暴露在Main里面了。
抽象工厂模式,可以和简单工厂或者工厂方法模式“组合在一起”,让后两者进一步封装抽象工厂中的Client。
严格的类图
总共14个java文件
- 两个抽象产品接口
- 四个具体产品类
- 一个抽象工厂接口
- 四个具体工厂类
- 一个Client类
- 一个封装Client类的简单工厂
- 一个Main类
图:我绘制的类图,严格的抽象工厂模式类图(一些资料不区分聚合、关联、依赖,把这三种关系统统当作依赖关系)。我使用了一个叫做AmaterasUML 的插件。
Talk is cheap, show me the code
两个抽象产品接口
package abstractFactory;
// 抽象产品A——蔬菜
public interface Veggies {
public String toString();
}
package abstractFactory;
// 抽象产品B——肉馅
public interface Meat {
public String toString();
}
四个具体产品类
package abstractFactory;
// 具体产品A1——白菜
public class Cabbage implements Veggies
{
public String toString()
{
return "白菜";
}
}
package abstractFactory;
// 具体产品A2——青椒
public class GreenPepper implements Veggies
{
public String toString()
{
return "青椒";
}
}
package abstractFactory;
// 具体产品B1——猪肉馅
public class Pork implements Meat {
public String toString()
{
return "猪肉";
}
}
package abstractFactory;
// 具体产品B2——牛肉馅
public