笔记:设计模式(3)-Abstract Factory抽象工厂模式
工厂模式的起源
1.变化点在“对象的创建”,因此就封装“对象创建”;
2.面向接口编程,依赖接口,而非依赖实现。
动机(Motivation)
在系统中,经常面临着“一系列相互以来的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象的创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?这就是我们要说的抽象工厂模式。
结构(Structure)
实现(Actionscript code)
//抽象工厂(AbstractFactory) package com.rock506.themes.abstract { import flash.errors.IllegalOperationError; public class AbstractThemeFactory { public function createSubmitButton():SubmitButton { throw new IllegalOperationError("abstract method"); return null; } public function createCancelButton():CancelButton { throw new IllegalOperationError("abstract method"); return null; } public function createMessageBox():MessageBox { throw new IllegalOperationError("abstract method"); return null; } } }
//抽象产品A(AbstractProductA) package com.rock506.themes.abstract { import flash.display.Sprite; import flash.errors.IllegalOperationError; public class Panel extends Sprite { public function Panel() { drawSkin(); } protected function drawSkin():void { throw new IllegalOperationError("abstract method"); } } }
//抽象产品B(AbstractProductB) package com.rock506.themes.abstract { import flash.display.Sprite; import flash.errors.IllegalOperationError; public class SubmitButton extends Sprite { public function SubmitButton() { drawSkin(); } protected function drawSkin():void { throw new IllegalOperationError("abstract method"); } } }
//具体产品A1(ConcreteProductA1) package com.rock506.themes.win7 { import com.rock506.themes.abstract.Panel; internal class Win7Panel extends Panel { public function Win7Panel() { super(); } protected override function drawSkin():void { trace("draw skin: Win7Panel"); } } }
//具体产品B1(ConcreteProductB1) package com.rock506.themes.win7 { import com.rock506.themes.abstract.SubmitButton; internal class Win7SubmitButton extends SubmitButton { public function Win7SubmitButton() { super(); } protected override function drawSkin():void { trace("draw skin: Win7SubmitButton"); } } }
//具体工厂(ConcreteFactory) package com.rock506.themes.win7 { import com.rock506.themes.abstract.*; public class Win7ThemeFactory extends AbstractThemeFactory { public override function createSubmitButton():SubmitButton { return new Win7SubmitButton(); } public override function createCancelButton():CancelButton { return new Win7CancelButton(); } public override function createMessageBox():MessageBox { return new Win7MessageBox(); } } }
//管理器 package com.rock506 { import com.rock506.themes.abstract.AbstractThemeFactory; import com.rock506.themes.abstract.CancelButton; import com.rock506.themes.abstract.Panel; import com.rock506.themes.abstract.SubmitButton; import flash.display.Sprite; public class ThemeManager { private var _theme:AbstractThemeFactory; public function ThemeManager(theme:AbstractThemeFactory) { _theme = theme; } public function BuildMessageBox():Sprite { var sp:Sprite = new Sprite(); var panel:Panel = _theme.createMessageBox(); var submitButton:SubmitButton = _theme.createSubmitButton(); var cancelButton:CancelButton = _theme.createCancelButton(); sp.addChild(panel); sp.addChild(submitButton); sp.addChild(cancelButton); return sp; } } }
//客户端 //使用xp主题 //var theme:ThemeManager = new ThemeManager(new XpThemeFactory()); //使用win7主题 var theme:ThemeManager = new ThemeManager(new Win7ThemeFactory()); var messageBox:Sprite = theme.BuildMessageBox(); addChild(messageBox);
实现要点(notice)
1.如果没有应对“多系列对象创建”的需求变化,则没有必要使用抽象工厂模式,这时候使用简单的静态工厂完全可以;
2. 系列对象指的是这些对象之间有相互依赖、或作用的关系;
3.抽象工厂模式经常和工厂方法模式共同组合来应对“对象创建”的需求变化;
4.把工厂作为单件,一个应用中一般每个产品系列只需一个具体工厂的实例,因此,工厂通常最好实现为一个单件模式。
参考文献(reference)
《C#面向对象设计模式纵横谈》视频