設計模式之原型模式(Prototype)(五)

動機

在軟件系統中,常常面臨着「某些結構複雜的對象」的建立工做;因爲需求的變化,這些對象常常面臨着劇烈的變化,可是它們卻擁有比較穩定一致的接口。設計模式

如何應對這種變化?如何向「客戶程序(使用這些對象的程序)」隔離出「這些易變對象」 ,從而使得「依賴這些易變對象的客戶程序」不隨着需求改變而改變?ide

 

意圖

使用原型實例指定建立對象的種類,而後經過拷貝這些原型來建立新的對象工具

 

示意圖

原型設計模式代碼實現

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;this

namespace 原型模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Computer computer = new Computer();
            computer.name = "Dell.X5124";
            computer.age = 5;
            computer.factory = new Factory() { name = "Dell" };
            computer.factory.manage = new Manage(){ManageName = "Nick"};spa

            Computer C1 = (computer as ICloneable).Clone() as Computer;
            C1.name = "Dell.X2546";
            C1.age = 6;
            C1.factory.name = "Sam";
            C1.factory.manage.ManageName = "jack";
            Console.WriteLine(computer);
            Console.WriteLine(C1);
            Console.ReadLine();
            
        }
    }設計

    public class Computer:ICloneable
    {
        public string name { get; set; }
        public int age { get; set; }指針

        public Factory factory { get; set; }orm

       


        public object Clone()
        {
            //return this.MemberwiseClone();//淺複製對象

            //如下實現深Copy接口

            var _Instace = this.MemberwiseClone() as Computer;
            _Instace.factory = (this.factory as ICloneable).Clone() as Factory;
            return _Instace;


        }

        public override string ToString()
        {
            return string.Format("電腦名字{0},使用年限{1},工廠名字{2},工廠管理者{3}",this.name,this.age,this.factory.name,this.factory.manage.ManageName);
        }
    }

    public class Factory:ICloneable
    {
        public string name { get; set; }
        public Manage manage { get; set; }

        public object Clone()//深Copy
        {
            var _Instace = base.MemberwiseClone() as Factory;
            _Instace.manage = (this.manage as ICloneable).Clone() as Manage;
            return _Instace;
        }
    }

    public class Manage:ICloneable
    {
        public string ManageName { get; set; }


        public object Clone()//淺Copy
        {
            return base.MemberwiseClone();
        }
    }

}
 

ICloneable和DataSet

 

ICloneable

public object Clone();

 

實現ICloneable接口,便可實現Prototype模式

 

DataSet

 

4lone():只複製結構,不復制數據à淺複製

Copy();複製結構,也複製數據à深複製

 

淺Copy與深Copy

若是一個對象是複合對象或者包含其餘的對象,那麼克隆對象的問題是僅僅複製對象自己,仍是連同被引用的對象一塊兒複製?

實現IClone接口的類基本上都採用淺複製的策略

MemberwiseClone():

值類型:逐位複製

引用類型:只複製引用(指針)但不復制引用的對象

深複製:把引用對象的變量,指向複製過的,新的對象,而不是原有的被引用的對象

 

實現要點

善用ICloneable接口

產品的建立和初始化在類的Clone方法中完成

淺複製與深複製的區別

須要深複製的場合須要開發人員根據須要實現

有些狀況下Clone功能不容易實現,特別是遇到對象的循環引用時

 

功能

在運行時增長或刪除產品:只要經過客戶原型實例便可將新產品類型增長到系統中,例如組態軟件中工具箱中的每一個工具能夠對應一個註冊的原型對象,能夠經過增長原形對象擴展工具箱。

很容易地建立複雜的對象:在圖形編輯和組態等軟件中,常常須要建立複雜的圖元。這些圖元是由簡單圖元組成的,採用原型模式能夠很容易地將複雜圖元做爲通常圖元來使用,使軟件的工具箱具備自擴展功能

 

適用性

當一個系統應該獨立於產品的建立、構成和表示時,可使用原型模式。

在使用時,咱們能夠用一些原型對象來代替生成相應對象的工廠對象,而且可使拷貝、粘貼等操做獨立於須要複製的對象。

 

總結

Prototype模式一樣用於隔離類對象的使用者和具體類型(易變類)之間的耦合關係,它一樣要求這些「易變類」擁有「穩定的接口」。

Prototype模式對於「如何建立易變類的實體對象」採用「原型克隆」的方法來作,它使得咱們能夠很是靈活地動態建立「擁有某些穩定接口」的新對象——所需工做僅僅是註冊一個新的對象(即原型),而後在任何須要的地方不斷地Clone。

Prototype模式中的Clone方法能夠利用.NET中的Object類的MemberwiseClone()方法或者序列化來實現深拷貝。

相關文章
相關標籤/搜索