Prototype原型模式(创建型模式)
1、原型模式解決的問(wèn)題
現(xiàn)在有一個(gè)抽象的游戲設(shè)施建造系統(tǒng),負(fù)責(zé)構(gòu)建一個(gè)現(xiàn)代風(fēng)格和古典風(fēng)格的房屋和道路.
前提:抽象變化較慢,實(shí)現(xiàn)變化較快(不穩(wěn)定)
整個(gè)抽象的游戲設(shè)施建造系統(tǒng)相對(duì)變化較慢,本例中只有一個(gè)Build的創(chuàng)建方法,而B(niǎo)uild內(nèi)部的方法實(shí)現(xiàn),該實(shí)現(xiàn)依賴與各種具體的實(shí)現(xiàn),而這些實(shí)現(xiàn)變化的非常頻繁,現(xiàn)在雖然只有現(xiàn)代風(fēng)格和古典風(fēng)格的房屋和道路的構(gòu)建,而將來(lái)可能會(huì)卡通風(fēng)格、另類風(fēng)格等各種各樣的對(duì)象加入到Build方法中來(lái)渲染游戲的背景.
在不考慮第三方容器組件(如Unity)和設(shè)計(jì)模式的情況下,為了快速完成這個(gè)任務(wù),我們通常會(huì)用以下這種方式編碼,代碼如下:
#region 抽象A/// <summary>/// 抽象的游戲設(shè)施建造系統(tǒng)/// </summary>public class BuildSystem{/// <summary>/// Build方法的邏輯變化較慢(只需要?jiǎng)?chuàng)建2種風(fēng)格的房屋和道路,總共8個(gè)對(duì)象),但是風(fēng)格變化較快,由于需求變化,可能需要?jiǎng)?chuàng)建諸如卡通風(fēng)格、另類風(fēng)格等的房屋和道路/// </summary>public void Builld(){ModernHouse modernHouseA = new ModernHouse();ModernHouse modernHouseB = new ModernHouse();ModernRoad modernRoadA = new ModernRoad();ModernRoad modernRoadB = new ModernRoad();ClassicalHouse classicalBuildA = new ClassicalHouse();ClassicalHouse classicalBuildB = new ClassicalHouse();ClassicalRoad classicalRoadA = new ClassicalRoad();ClassicalRoad classicalRoadB = new ClassicalRoad();//下面是具體的對(duì)象實(shí)例操作,如現(xiàn)代化房屋雖然有兩個(gè)實(shí)例,但是可能兩個(gè)可能高矮、外形不同等 }} #endregion#region 實(shí)現(xiàn)細(xì)節(jié)b/// <summary>/// 現(xiàn)代風(fēng)格的房屋/// </summary>public class ModernHouse { }/// <summary>/// 現(xiàn)代風(fēng)格的道路/// </summary>public class ModernRoad { }/// <summary>/// 古典風(fēng)格的房屋/// </summary>public class ClassicalHouse { }/// <summary>/// 古典風(fēng)格的道路/// </summary>public class ClassicalRoad { } #endregion從oop的角度分析上面的代碼,可以理解為抽象的游戲系統(tǒng)直接依賴具體的實(shí)現(xiàn)細(xì)節(jié)(現(xiàn)代風(fēng)格和古典風(fēng)格的房屋和道路),如下圖:
這時(shí)客戶端的調(diào)用代碼如下:
/// <summary>/// Prototype原型模式-創(chuàng)建型模式/// </summary>class Program{static void Main(string[] args){BuildSystem buildSystem = new BuildSystem();buildSystem.Builld();}}這種設(shè)計(jì)方式的弊端顯而易見(jiàn),Build方法顯得很無(wú)力,這個(gè)時(shí)候增加了一個(gè)新的需求,如下:
客戶端需要構(gòu)建一種卡通風(fēng)格和另類風(fēng)格的道路和房屋,但是Build方法的主邏輯還是不變,同樣是(創(chuàng)建兩種風(fēng)格的房屋和道路,共8個(gè)對(duì)象).
這時(shí)Build方法顯得很無(wú)力,只能創(chuàng)建一種特定邏輯的游戲背景建筑.(當(dāng)然你可以在BuildSystem中新添一種新的Build方法來(lái)滿足需求,但是這種方式的代碼的重用性差)而且,掉到了,抽象依賴于實(shí)現(xiàn)的坑里面去了,這個(gè)時(shí)候我們就需要對(duì)代碼進(jìn)行重構(gòu),進(jìn)行依賴倒置.如下圖:
對(duì)所有的Build方法中的8個(gè)實(shí)例(實(shí)現(xiàn)細(xì)節(jié)b)進(jìn)行抽象,讓它們依賴于抽象B,讓Build方法(抽象A)也依賴于抽象B,代碼如下:
#region 抽象A/// <summary>/// 抽象的游戲設(shè)施建造系統(tǒng)/// </summary>public class BuildSystem{/// <summary>/// Build方法的邏輯變化較慢(只需要?jiǎng)?chuàng)建2種風(fēng)格的房屋和道路,總共8個(gè)對(duì)象),但是風(fēng)格變化較快,由于需求變化,可能需要?jiǎng)?chuàng)建諸如卡通風(fēng)格、另類風(fēng)格等的房屋和道路/// </summary>public void Builld(House houseone, House houseTwo,Road roadone, Road roadtwo){House modernHouseA = houseone.Clone();House modernHouseB = houseone.Clone();Road modernRoadA = roadone.Clone();Road modernRoadB = roadone.Clone();House classicalBuildA = houseTwo.Clone();House classicalBuildB = houseTwo.Clone();Road classicalRoadA = roadtwo.Clone();Road classicalRoadB = roadtwo.Clone();//下面是具體的對(duì)象實(shí)例操作,如現(xiàn)代化房屋雖然有兩個(gè)實(shí)例,但是可能兩個(gè)可能高矮、外形不同等 }}#endregion#region 抽象B/// <summary>/// 抽象房屋/// </summary>public abstract class House{/// <summary>/// 抽象的House的Clone方法,用于構(gòu)建House的多個(gè)實(shí)例,如果抽象A只需要一個(gè)實(shí)現(xiàn)b的一個(gè)實(shí)例,則不需要該方法/// </summary>/// <returns></returns>public abstract House Clone();}/// <summary>/// 抽象道路/// </summary>public abstract class Road{/// <summary>/// 抽象的Road的Clone方法,用于構(gòu)建Road的多個(gè)實(shí)例,如果抽象A只需要一個(gè)實(shí)現(xiàn)b的一個(gè)實(shí)例,則不需要該方法/// </summary>/// <returns></returns>public abstract Road Clone();}#endregion#region 實(shí)現(xiàn)細(xì)節(jié)b/// <summary>/// 現(xiàn)代風(fēng)格的房屋/// </summary>public class ModernHouse : House{public override House Clone(){//實(shí)現(xiàn)ModernHouse的淺拷貝,如果當(dāng)前對(duì)象中含有數(shù)組等,則需要使用序列化的方式(深拷貝)實(shí)現(xiàn)對(duì)象的克隆,否則當(dāng)一個(gè)對(duì)象實(shí)例修改了數(shù)組,另一個(gè)對(duì)象實(shí)例會(huì)共享該數(shù)組return (ModernHouse)MemberwiseClone();}}/// <summary>/// 現(xiàn)代風(fēng)格的道路/// </summary>public class ModernRoad : Road{public override Road Clone(){return (ModernRoad)MemberwiseClone();}}/// <summary>/// 古典風(fēng)格的房屋/// </summary>public class ClassicalHouse : House{public override House Clone(){return (House)MemberwiseClone();}}/// <summary>/// 古典風(fēng)格的道路/// </summary>public class ClassicalRoad: Road{public override Road Clone(){return (ClassicalRoad)MemberwiseClone();}}/// <summary>/// 卡通風(fēng)格的房屋/// </summary>public class CartoonHouse : House{public override House Clone(){return (CartoonHouse)MemberwiseClone();}}/// <summary>/// 卡通風(fēng)格的道路/// </summary>public class CartoonRoad : Road{public override Road Clone(){return (CartoonRoad)MemberwiseClone();}}/// <summary>/// 另類風(fēng)格的房屋/// </summary>public class AlternativeHouse : House{public override House Clone(){return (AlternativeHouse)MemberwiseClone();}}/// <summary>/// 另類風(fēng)格的道路/// </summary>public class AlternativeRoad : Road{public override Road Clone(){return (AlternativeRoad)MemberwiseClone();}}#endregion?
這時(shí)客戶端的調(diào)用代碼如下:
class Program{static void Main(string[] args){BuildSystem buildSystem = new BuildSystem();//構(gòu)建卡通風(fēng)格和另類風(fēng)格的房屋和道路buildSystem.Builld(new CartoonHouse(), new AlternativeHouse(), new CartoonRoad(), new AlternativeRoad());//構(gòu)建現(xiàn)代風(fēng)格和古典風(fēng)格的房屋和道路buildSystem.Builld(new ModernHouse(),new ClassicalHouse(),new ModernRoad(),new ClassicalRoad());}}ok,重構(gòu)后的代碼,在抽象A相對(duì)穩(wěn)定的情況,通過(guò)對(duì)實(shí)現(xiàn)細(xì)節(jié)b的抽象,讓實(shí)現(xiàn)細(xì)節(jié)b和抽象A都依賴于抽象B,完成了依賴倒置,實(shí)現(xiàn)了代碼new的解耦,這就是原型模式!
?
關(guān)于原型模式的幾個(gè)要點(diǎn):
1、Prototype模式用于隔離類對(duì)象的使用者和具體類型(易變類)的之間的耦合關(guān)系,但是這些易變類必須擁有穩(wěn)定的接口.
2、Prototype模式對(duì)于"如何創(chuàng)建易變類的對(duì)象"采用"原型克隆"的方式來(lái)做,它使我們能非常靈活動(dòng)態(tài)的創(chuàng)建某些擁有"穩(wěn)定接口"的新對(duì)象.所需的工作僅僅是創(chuàng)建一個(gè)新類的對(duì)象即原型,然后在需要的地方不斷的Clone.
3、Prototype模式的Clone方法可以利用Object自帶的MemberwiseClone方法,注:該方法只能用于比較簡(jiǎn)單的類,只能實(shí)現(xiàn)淺拷貝,如果類中包含數(shù)組等引用類型,則需要使用序列化方法來(lái)實(shí)現(xiàn)類型的深拷貝
?
轉(zhuǎn)載于:https://www.cnblogs.com/GreenLeaves/p/9788981.html
總結(jié)
以上是生活随笔為你收集整理的Prototype原型模式(创建型模式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: How to Pronounce BEA
- 下一篇: AttributeError: modu