原型模式(建立型模式)

來源:互聯網
上載者:User

標籤:alt   ide   工作   end   代碼   system   靈活   關於   abs   

1、原型模式解決的問題

現在有一個抽象的遊戲設施建造系統,負責構建一個現代風格和古典風格的房屋和道路.

前提:抽象變化較慢,實現變化較快(不穩定)

整個抽象的遊戲設施建造系統相對變化較慢,本例中只有一個Build的建立方法,而Build內部的方法實現,該實現依賴與各種具體的實現,而這些實現變化的非常頻繁,現在雖然只有現代風格和古典風格的房屋和道路的構建,而將來可能會卡通風格、另類風格等各種各樣的對象加入到Build方法中來渲染遊戲的背景.

在不考慮第三方容器組件(如Unity)和設計模式的情況下,為了快速完成這個任務,我們通常會用以下這種方式編碼,代碼如下:

    #region 抽象A    /// <summary>    /// 抽象的遊戲設施建造系統    /// </summary>    public class BuildSystem    {        /// <summary>        /// Build方法的邏輯變化較慢(只需要建立2種風格的房屋和道路,總共8個對象),但是風格變化較快,由於需求變化,可能需要建立諸如卡通風格、另類風格等的房屋和道路        /// </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();            //下面是具體的對象執行個體操作,如現代化房屋雖然有兩個執行個體,但是可能兩個可能高矮、外形不同等        }    }     #endregion    #region 實現細節b    /// <summary>    /// 現代風格的房屋    /// </summary>    public class ModernHouse { }    /// <summary>    /// 現代風格的道路    /// </summary>    public class ModernRoad { }    /// <summary>    /// 古典風格的房屋    /// </summary>    public class ClassicalHouse { }    /// <summary>    /// 古典風格的道路    /// </summary>    public class ClassicalRoad { }     #endregion

從oop的角度分析上面的代碼,可以理解為抽象的遊戲系統直接依賴具體的實現細節(現代風格和古典風格的房屋和道路),如:

這時用戶端的調用代碼如下:

    /// <summary>    /// Prototype原型模式-建立型模式    /// </summary>    class Program    {        static void Main(string[] args)        {            BuildSystem buildSystem = new BuildSystem();            buildSystem.Builld();        }    }

這種設計方式的弊端顯而易見,Build方法顯得很無力,這個時候增加了一個新的需求,如下:

用戶端需要構建一種卡通風格和另類風格的道路和房屋,但是Build方法的主邏輯還是不變,同樣是(建立兩種風格的房屋和道路,共8個對象).

這時Build方法顯得很無力,只能建立一種特定邏輯的遊戲背景建築.(當然你可以在BuildSystem中新添一種新的Build方法來滿足需求,但是這種方式的代碼的重用性差)而且,掉到了,抽象依賴於實現的坑裡面去了,這個時候我們就需要對代碼進行重構,進行依賴倒置.如:

對所有的Build方法中的8個執行個體(實現細節b)進行抽象,讓它們依賴於抽象B,讓Build方法(抽象A)也依賴於抽象B,代碼如下:

    #region 抽象A    /// <summary>    /// 抽象的遊戲設施建造系統    /// </summary>    public class BuildSystem    {        /// <summary>        /// Build方法的邏輯變化較慢(只需要建立2種風格的房屋和道路,總共8個對象),但是風格變化較快,由於需求變化,可能需要建立諸如卡通風格、另類風格等的房屋和道路        /// </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();            //下面是具體的對象執行個體操作,如現代化房屋雖然有兩個執行個體,但是可能兩個可能高矮、外形不同等        }    }    #endregion    #region 抽象B    /// <summary>    /// 抽象房屋    /// </summary>    public abstract class House    {        /// <summary>        /// 抽象的House的Clone方法,用於構建House的多個執行個體,如果抽象A只需要一個實現b的一個執行個體,則不需要該方法        /// </summary>        /// <returns></returns>        public abstract House Clone();    }    /// <summary>    /// 抽象道路    /// </summary>    public abstract class Road    {        /// <summary>        ///  抽象的Road的Clone方法,用於構建Road的多個執行個體,如果抽象A只需要一個實現b的一個執行個體,則不需要該方法        /// </summary>        /// <returns></returns>        public abstract Road Clone();    }    #endregion    #region 實現細節b    /// <summary>    /// 現代風格的房屋    /// </summary>    public class ModernHouse : House    {        public override House Clone()        {            //實現ModernHouse的淺拷貝,如果當前對象中含有數組等,則需要使用序列化的方式(深拷貝)實現對象的複製,否則當一個對象執行個體修改了數組,另一個對象執行個體會共用該數組            return (ModernHouse)MemberwiseClone();        }    }    /// <summary>    /// 現代風格的道路    /// </summary>    public class ModernRoad : Road    {        public override Road Clone()        {            return (ModernRoad)MemberwiseClone();        }    }    /// <summary>    /// 古典風格的房屋    /// </summary>    public class ClassicalHouse : House    {        public override House Clone()        {            return (House)MemberwiseClone();        }    }    /// <summary>    /// 古典風格的道路    /// </summary>    public class ClassicalRoad: Road    {        public override Road Clone()        {            return (ClassicalRoad)MemberwiseClone();        }    }    /// <summary>    /// 卡通風格的房屋    /// </summary>    public class CartoonHouse : House    {        public override House Clone()        {            return (CartoonHouse)MemberwiseClone();        }    }    /// <summary>    /// 卡通風格的道路    /// </summary>    public class CartoonRoad : Road    {        public override Road Clone()        {            return (CartoonRoad)MemberwiseClone();        }    }    /// <summary>    /// 另類風格的房屋    /// </summary>    public class AlternativeHouse : House    {        public override House Clone()        {            return (AlternativeHouse)MemberwiseClone();        }    }    /// <summary>    /// 另類風格的道路    /// </summary>    public class AlternativeRoad : Road    {        public override Road Clone()        {            return (AlternativeRoad)MemberwiseClone();        }    }    #endregion

 

這時用戶端的調用代碼如下:

    class Program    {        static void Main(string[] args)        {            BuildSystem buildSystem = new BuildSystem();            //構建卡通風格和另類風格的房屋和道路            buildSystem.Builld(new CartoonHouse(), new AlternativeHouse(), new CartoonRoad(), new AlternativeRoad());            //構建現代風格和古典風格的房屋和道路            buildSystem.Builld(new ModernHouse(),new ClassicalHouse(),new ModernRoad(),new ClassicalRoad());        }    }

ok,重構後的代碼,在抽象A相對穩定的情況,通過對實現細節b的抽象,讓實現細節b和抽象A都依賴於抽象B,完成了依賴倒置,實現了代碼new的解耦,這就是原型模式!

 

關於原型模式的幾個要點:

1、Prototype模式用於隔離類對象的使用者和具體類型(易變類)的之間的耦合關係,但是這些易變類必須擁有穩定的介面.

2、Prototype模式對於"如何建立易變類的對象"採用"原型複製"的方式來做,它使我們能非常靈活動態建立某些擁有"穩定介面"的新對象.所需的工作僅僅是建立一個新類的對象即原型,然後在需要的地方不斷的Clone.

3、Prototype模式的Clone方法可以利用Object內建的MemberwiseClone方法,注:該方法只能用於比較簡單的類,只能實現淺拷貝,如果類中包含數組等參考型別,則需要使用序列化方法來實作類別型的深拷貝

 

原型模式(建立型模式)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.