笔记:设计模式(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#面向对象设计模式纵横谈》视频

http://terrylee.cnblogs.com

 

 

posted @ 2010-09-21 01:56  rock506  阅读(350)  评论(0编辑  收藏  举报