前一篇文章,介紹了工廠方法,並且,探討了下工廠方法的不足之處:
及我們知道,在工廠方法中,每個 Creator,只是創建單一的實例,那對於一次要創建n多不同的類實例的情況呢?
及,如果我們要實現這樣的方法呢?:
using System;
using System.Collections.Generic;
using System.Text;
namespace 工廠方法
{
public interface ICreator<T> where T : IDomain
{
ISpeciality<T> CreaterSpeciality( );
//這裏帶上其他的類的創建方法
}
}
抽象工廠,爲我們很好的解決了這個問題。
如在一個農場中,會種植水果和蔬菜。而蔬菜和水果的種類,又因地域的不同而不同,如:南方的農民種植的水果爲荔枝,蔬菜爲苦瓜,北方的農民種植的水果是紅棗,蔬菜是大白菜。一個農場的農民,農場主不可能要求他的工人在會種植一樣東西,需要都能夠種植。用程序來解釋,如下:
農民接口:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public interface 農民接口
{
蔬菜接口 種植蔬菜();
水果接口 種植水果();
}
}
水果接口:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
/// <summary>
/// 水果的接口
/// </summary>
public interface 水果接口
{
/// <summary>
/// 水果的味道
/// </summary>
/// <returns></returns>
string 味道();
/// <summary>
/// 水果生長週期
/// </summary>
/// <returns></returns>
int 水果生長週期();
/// <summary>
/// 水果生長區域
/// </summary>
/// <returns></returns>
string 生長區域();
}
}
蔬菜接口:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
/// <summary>
/// 蔬菜接口
/// </summary>
public interface 蔬菜接口
{
/// <summary>
/// 蔬菜生長區域
/// </summary>
/// <returns></returns>
string 生長區域();
/// <summary>
/// 一棵種子是否只長一個果實
/// </summary>
/// <returns></returns>
bool 一棵種子是否只長一個果實();
}
}
各種水果類:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
/// <summary>
/// 荔枝類 南方生產的水果
/// </summary>
public class 荔枝 : 水果接口
{
public string 味道()
{
return "荔枝非常的甜";
}
public int 水果生長週期()
{
return 1;
}
public string 生長區域()
{
return "南方";
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public class 紅棗 : 水果接口
{
public string 味道()
{
return "紅棗有點甜";
}
public int 水果生長週期()
{
return 1;
}
public string 生長區域()
{
return "北方";
}
}
}
各種蔬菜類:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public class 大白菜 : 蔬菜接口
{
public string 生長區域()
{
return "北方";
}
public bool 一棵種子是否只長一個果實()
{
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public class 苦瓜 : 蔬菜接口
{
public string 生長區域()
{
return "南方";
}
public bool 一棵種子是否只長一個果實()
{
return false;
}
}
}
農民類:
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public class 南方農民 : 農民接口
{
public 蔬菜接口 種植蔬菜()
{
return new 苦瓜();
}
public 水果接口 種植水果()
{
return new 荔枝();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace 抽象工廠
{
public class 北方農民 : 農民接口
{
public 蔬菜接口 種植蔬菜()
{
return new 大白菜();
}
public 水果接口 種植水果()
{
return new 紅棗();
}
}
}
使用的時候:
private void button1_Click(object sender, EventArgs e)
{
農民接口 一個農民 = new 南方農民();
水果接口 水果 = 一個農民.種植水果();
蔬菜接口 蔬菜 = 一個農民.種植蔬菜();
}
這樣,南方的農民就可以同時種植南方的水果和南方的蔬菜了,也就解決了一個農民只能夠種植一種東西的情況,也就是解決了工廠方法的問題。
抽象工廠 和 建造者buileder的不同:
首先,抽象工廠返回的是一個完完全全的產品對象,客戶端 可以根據這些產品對象,再去組裝出更加複雜的產品對象。
而建造者,返回的不是一個完整的產品對象,客戶端需要自己在去把產品的各個部件在組裝起來。
如果兩個模式結合起來用,情況可以這樣:
如在一個遊戲中,如:西山居 開發的 劍俠情緣 來說,一張地圖上,需要建立房子,道路,路標,廣告牌等等,
一張地圖,需要創建這些東西,而這些房子呀什麼的,又有不同的風格,建造者+抽象工廠,就可以能夠滿足這個地圖的創建(呵呵,對於該遊戲到底是怎麼弄的,我是不知道,自己亂想的)
上面的程序,用的中文表示,呵呵,一是測試vs裏面能夠用中文不,二是這樣看起來容易點。