书中的工厂模式分成了两章来叙述,只区分工厂方法模式和抽象工厂模式,因为简单工厂模式只是工厂方法模式中的一个特例。但是书中举的例子我觉得没那么好理解,于是自己设定了一个应用场景来帮助理解这三种设计模式。
(一)简单工厂模式
假设有如下场景:
有一个页面,上面有个Button,Button的风格有ButtonA和ButtonB两种,设置一能够让Button风格切换。此场景可以应用简单工厂模式:
public class ButtonFactory{
public Button createButton(String type){
switch (type){
case "A":
return new ButtonA();
case "B":
return new ButtonB();
}
}
}
public abstract class Button{
public Button(){
}
}
public class ButtonA extends Button{
public ButtonA(){
}
}
public class ButtonB extends Button{
public ButtonB(){
}
}
(二)工厂方法模式
基于以上的场景,假如该页面出了Button,还有对应的Background,Background也有两种风格BackgroundA和BackgroundB,设置二能够改变Background的风格。假如继续使用上面的简单工厂模式,则ButtonFactory需要继续增加Background相关的判断,这显然不太适合,因为ButtonFactory就是设计来创建Button的。这时候就可以使用工厂方法模式了。区别与简单工厂,工厂方法增加了一个抽象的工厂类ViewFactory,然后多创建一个BackgroundFactory的具体工厂来创建Background,这两个工厂都继承自ViewFactory。
public abstract class View{
public View();
}
public class ButtonA extends View{
public ButtonA(){}
}
public class ButtonB extends View{
public ButtonB(){}
}
public class BackgroundA extends View{
public BackgroundA(){}
}
public class BackgroundB extends View{
public BackgroundB(){}
}
public abstract class ViewFactory{
abstract View createView(String type);
}
public class ButtonFactory extends ViewFactory{
View createView(String type){
case "A":
return new ButtonA();
case "B":
return new ButtonB();
}
}
public class BackgroundFactory extends ViewFactory{
View createView(String type){
case "A":
return new BackgroundA();
case "B":
return new BackgroundB();
}
}
(三)抽象工厂模式
继续基于以上场景,假如设置三能够是Button和Background同时发生切换,即ButtonA匹配BackgroundA,ButtonB匹配BackgroundB。此时就可以使用抽象工厂模式。区别与工厂方法,抽象工厂的工厂类可以创建不止一种产品(Button和Background),而产品类别也不止一种(将Button和Background分开为两种类别的产品)。
public abstract class Button{
public Button(){
}
}
public class ButtonA extends Button{
public ButtonA(){
}
}
public class ButtonB extends Button{
public ButtonB(){
}
}
public abstract class Background{
public Button(){
}
}
public class BackgroundA extends Background{
public BackgroundA(){
}
}
public class BackgroundB extends Background{
public BackgroundB(){
}
}
public abstract class UIFactory{
abstract Button createButton();
abstract Background createBackground();
}
public class UIAFactory extends UIFactory{
public Button createButton(){
return new ButtonA();
}
public Background createBackground(){
return new BackgroundA();
}
}
public class UIBFactory extends UIFactor{
public Button createButton(){
return new ButtonB();
}
public Background createBackground(){
return new BackgroundB();
}
}