设计模式-抽象工厂模式
提供用于创建一系列具有独立产品形态的抽象产品的接口,每个抽象产品可以派生出多个具体产品。
举个例子吧,大家都知道家具厂会生产床、桌子、椅子、书柜、大衣柜等等种类繁多的家具,通过这些家具的组合可以设计出各种风格的居家格局。
比如对于床来说,有儿童床和成人床,儿童床和成人床的生产过程是有区别的。对于桌子来说,有儿童桌和成人办公桌,儿童桌和成人办公桌的生产方式肯定也是不一样的。这里其实就有两个独立产品形态的抽象:床和桌子。但是厂家希望生产不同种类的床和桌子,即希望通过床和桌子这两个抽象产品派生出多个具体的床和桌子。
好了,先描述到这,上类图可以更加清楚的说明问题
UML类图
如上图所示,ChildBed
和AdultBed
这两个具体产品实现了接口Bed
。ChildDesk
和AdultOfficeDesk
这两个具体产品实现了接口Desk
。Bed
和Desk
这是两个具有独立产品形态的产品。
FurnitureFactory
是抽象工厂,它有两个接口分别用于创建Bed
和Desk
系列的产品。ChildFurnitureFactory
和AdultFurnitureFactory
这两个具体工厂实现了抽象工厂FurnitureFactory
,每个具体工厂负责生产相关联的产品。例如ChildFurnitureFactory
负责生产儿童需要的家具(这里包括床和桌子,当然还可以有其他儿童用的家具),AdultFurnitureFactory
负责生产成人需要的家具。
代码实现
‘床’的接口, Bed
/**
* <p>文件描述: '床'的抽象</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:44
*/
public interface Bed {
void bedDescription();
}
儿童床, ChildBed
/**
* <p>文件描述: 儿童床</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:47
*/
public class ChildBed implements Bed {
@Override
public void bedDescription() {
System.out.println("我是儿童床");
}
}
成人床, AdultBed
/**
* <p>文件描述: 成人床</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:48
*/
public class AdultBed implements Bed {
@Override
public void bedDescription() {
System.out.println("我是成人床");
}
}
‘桌子’的接口, Desk
/**
* <p>文件描述: '桌子'的抽象</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:46
*/
public interface Desk {
void deskDescription();
}
儿童桌子, ChildDesk
/**
* <p>文件描述: 儿童桌</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:49
*/
public class ChildDesk implements Desk {
@Override
public void deskDescription() {
System.out.println("我是儿童桌子");
}
}
成人办公桌, AdultOfficeDesk
/**
* <p>文件描述: 成人办公桌</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:50
*/
public class AdultOfficeDesk implements Desk {
@Override
public void deskDescription() {
System.out.println("我是成人办公桌");
}
}
家具抽象工厂接口, FurnitureFactory
/**
* <p>文件描述: 抽象工厂</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:51
*/
public interface FurnitureFactory {
Bed produceBed();
Desk produceDesk();
}
儿童家具工厂, ChildFurnitureFactory
/**
* <p>文件描述: 儿童家具工厂</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:52
*/
public class ChildFurnitureFactory implements FurnitureFactory {
@Override
public Bed produceBed() {
return new ChildBed();
}
@Override
public Desk produceDesk() {
return new ChildDesk();
}
}
成人家具工厂, AdultFurnitureFactory
/**
* <p>文件描述: 成人家具工厂</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:53
*/
public class AdultFurnitureFactory implements FurnitureFactory {
@Override
public Bed produceBed() {
return new AdultBed();
}
@Override
public Desk produceDesk() {
return new AdultOfficeDesk();
}
}
抽象工厂Demo类, AbstractFactoryDemo
/**
* <p>文件描述: 抽象工厂Demo类</p>
*
* @Author luanmousheng
* @Date 17/6/19 下午10:54
*/
public class AbstractFactoryDemo {
public static void main(String[] args) {
FurnitureFactory childFurnitureFactory = new ChildFurnitureFactory();
Bed childBed = childFurnitureFactory.produceBed();
childBed.bedDescription();
Desk childDesk = childFurnitureFactory.produceDesk();
childDesk.deskDescription();
}
}
Demo类输出结果为
我是儿童床
我是儿童桌子
优缺点
优点:当一系列具有独立形态的产品在一起工作时,客户端只需要初始化一次工厂即可创建这一系列的产品。
缺点:当新增一个产品时,需要更改的地方太多。比如新增一个Chair
系列的产品,需要添加Chair
接口、ChildChair
类、AdultChair
类,还要修改FuinitureFactory
、 ChildFuinitureFactory
、 AdultFuinitureFactory
。