案例
在 工厂方法模式 的案例基础上,为农夫山泉、咖啡增加了常温、加热两种状态。
/*
1. 抽象产品接口(水)
*/
public interface Water {
public void getWaterType();
public void getWaterTemperature();
}
/*
* 抽象的产品类(咖啡)
*/
public abstract class AbstractCoffee implements Water{
public void getWaterType(){
System.out.println("这是一杯咖啡");
}
}
/*
* 抽象的产品类(农夫山泉)
*/
public abstract class AbstractNongFuSpring implements Water{
public void getWaterType(){
System.out.println("这是一瓶农夫山泉");
}
}
/*
* 具体产品类:热的咖啡
*/
public class HotCoffee extends AbstractCoffee{
@Override
public void getWaterTemperature() {
System.out.println("咖啡是热的……");
}
}
/*
* 具体产品类:热的农夫山泉
*/
public class HotNongFuSpring extends AbstractNongFuSpring{
@Override
public void getWaterTemperature() {
System.out.println("农夫山泉是热的……");
}
}
/*
* 具体产品类:常温的咖啡
*/
public class NormalCoffee extends AbstractCoffee{
@Override
public void getWaterTemperature() {
System.out.println("咖啡是常温的");
}
}
/*
* 具体产品类:常温的农夫山泉
*/
public class NormalNongFuSpring extends AbstractNongFuSpring{
@Override
public void getWaterTemperature() {
System.out.println("农夫山泉是常温的");
}
}
/*
* 抽象工厂接口
*/
public interface Creator {
public Water createCoffee();
public Water createNongFuSpring();
}
/*
* 具体工厂类(热饮)
*/
public class HotCreator implements Creator{
@Override
public Water createCoffee() {
return new HotCoffee();
}
@Override
public Water createNongFuSpring() {
return new HotNongFuSpring();
}
}
/*
* 具体工厂类(常温饮品)
*/
public class NormalCreator implements Creator{
@Override
public Water createCoffee() {
return new NormalCoffee();
}
@Override
public Water createNongFuSpring() {
return new NormalNongFuSpring();
}
}
/*
* 使用场景
*/
public class Scene {
public static void main(String[] args) {
Creator hotCreator = new HotCreator();
Creator normalCreator = new NormalCreator();
//生产一杯热的咖啡
Water coffee = hotCreator.createCoffee();
coffee.getWaterType();
coffee.getWaterTemperature();
//生产一瓶热的农夫山泉
Water nongFuSpring = hotCreator.createNongFuSpring();
nongFuSpring.getWaterType();
nongFuSpring.getWaterTemperature();
}
}
优点
- 封装性良好
- 产品族内的约束为非公开状态。如:在饮品的产量上,常温饮品的产量与热饮的产量之间有一个约束(2:1)存在,这样的生产过程对调用工厂类的高层模块而言是透明的,因为其具体的实现过程是在工厂内完成的
缺点
- 产品族的扩展会比较困难。如:增加一个产品(可口可乐),会牵涉到哪些类的改动?
使用场景
- 一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。如:一个文本编辑器和一个图片处理器,都是软件实体,但是Unix 下的文本编辑器和 Windows 下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也有类似情况。也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。