參考文章
http://www.cnblogs.com/zhenyulu/articles/36590.html
http://wenku.baidu.com/view/e9b3a36a1eb91a37f1115cf2.html
代碼和内容都是本人親自測試。
一 工廠方法(Factory Method)模式
在軟體系統中,由于需求的變化,這個對象的具體實作經常面臨着劇烈的變化,但它卻有比較穩定的接口。
定義一個使用者建立對象的接口,讓子類決定執行個體哪一個類。Factory Method使一個類的執行個體化延遲到子類。
在工廠方法模式中,核心的工廠類不再負責所有産品的建立,而是将具體建立工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實作的接口,而不接觸哪一個産品類被執行個體化這種細節。這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新産品。
在Factory Method模式中,工廠類與産品類往往具有平行的等級結構,它們之間一一對應。
二 工廠方法模式的角色
抽象工廠(Creator)角色:是工廠方法模式的核心,與應用程式無關。任何在模式中建立的對象的工廠類必須實作這個接口。
具體工廠(Concrete Creator)角色:這是實作抽象工廠接口的具體工廠類,包含與應用程式密切相關的邏輯,并且受到應用程式調用以建立産品對象。在上圖中有兩個這樣的角色:BulbCreator與TubeCreator。
抽象産品(Product)角色:工廠方法模式所建立的對象的超類型,也就是産品對象的共同父類或共同擁有的接口。在上圖中,這個角色是Light。
具體産品(Concrete Product)角色:這個角色實作了抽象産品角色所定義的接口。某具體産品有專門的具體工廠建立,它們之間往往一一對應。
三 一個例子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FactoryMethod
{
public abstract class Light
{
public abstract void TurnOn();
public abstract void TurnOff();
}
public class BulbLight : Light
{
public override void TurnOn()
{
Console.WriteLine("BulbLight is turn on");
}
public override void TurnOff()
{
Console.WriteLine("BulbLight is turn off");
}
}
public class TubeLight : Light
{
public override void TurnOn()
{
Console.WriteLine("TubeLight is turn on");
}
public override void TurnOff()
{
Console.WriteLine("TubeLight is turn off");
}
}
public abstract class Creator
{
public abstract Light factory();
}
public class BulbCreator : Creator
{
public override Light factory()
{
return new BulbLight();
}
}
public class TubeCreator : Creator
{
public override Light factory()
{
return new TubeLight();
}
}
public class Client
{
static void Main(string[] args)
{
Creator c1 = new BulbCreator();
Creator c2 = new TubeCreator();
Light l1 = c1.factory();
l1.TurnOn();
l1.TurnOff();
Console.WriteLine("-----------------");
l1 = c2.factory();
l1.TurnOn();
l1.TurnOff();
}
}
}
可以跟簡單工廠進行比較
1 工廠類也定義一個基本的抽象類,不實作邏輯和執行個體化。
2 不同産品有自己的不同的工廠類來實作。在調用的時候用不同類的相同工廠方法建立執行個體。
四 工廠方法模式與簡單工廠模式
工廠方法模式與簡單工廠模式再結構上的不同不是很明顯。工廠方法類的核心是一個抽象工廠類,而簡單工廠模式把核心放在一個具體類上。
工廠方法模式之是以有一個别名叫多态性工廠模式是因為具體工廠類都有共同的接口,或者有共同的抽象父類。
當系統擴充需要添加新的産品對象時,僅僅需要添加一個具體對象以及一個具體工廠對象,原有工廠對象不需要進行任何修改,也不需要修改用戶端,很好的符合了"開放-封閉"原則。而簡單工廠模式在添加新産品對象後不得不修改工廠方法,擴充性不好。
工廠方法模式退化後可以演變成簡單工廠模式。
五 另外一個例子
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace FactoryMethod2
{
abstract class Page
{
}
class SkillsPage : Page
{
}
class EducationPage : Page
{
}
class ExperiencePage : Page
{
}
class IntroductionPage : Page
{
}
class ResultPage : Page
{
}
class ConclusionPage : Page
{
}
class SummaryPage : Page
{
}
class BibliographyPage : Page
{
}
abstract class Document
{
protected ArrayList pages = new ArrayList();
public Document()
{
this.CreatPages();
}
public ArrayList Pages
{
get { return pages; }
}
abstract public void CreatPages();
}
class Resume : Document
{
public override void CreatPages()
{
pages.Add(new SkillsPage());
pages.Add(new EducationPage());
pages.Add(new ExperiencePage());
}
}
class Report : Document
{
public override void CreatPages()
{
pages.Add(new IntroductionPage());
pages.Add(new ResultPage());
pages.Add(new ConclusionPage());
pages.Add(new SummaryPage());
pages.Add(new BibliographyPage());
}
}
class Client
{
static void Main(string[] args)
{
Document[] docs = new Document[2];
docs[0]= new Resume();
docs[1] = new Report();
foreach (Document temp in docs)
{
Console.WriteLine(" " + temp + " ------- ");
foreach (Page page in temp.Pages)
{
Console.WriteLine(" " + page);
}
Console.WriteLine("");
}
}
}
}
第二個例子比第一個例子更加的直覺。
Factory Method模式主要用于隔離類對象的使用者和具體類型之間的耦合關系。面對一個經常變化的具體類型,緊耦合關系會導緻軟體的脆弱。
Factory Method模式通過面向對象的手法,将所要建立的具體對象工作延遲到子類,進而實作一種擴充(而非更改)的政策,較好地解決了這種緊耦合關系。