溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么理解Java設(shè)計(jì)模式的原型模式

發(fā)布時(shí)間:2021-11-08 09:01:31 來(lái)源:億速云 閱讀:166 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容主要講解“怎么理解Java設(shè)計(jì)模式的原型模式”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么理解Java設(shè)計(jì)模式的原型模式”吧!

    一、前言

    單例模式可以避免重復(fù)創(chuàng)建消耗資源的對(duì)象,但是卻不得不共用對(duì)象。若是對(duì)象本身也不讓隨意訪問(wèn)修改時(shí),怎么辦?通常做法是備份到副本,其它對(duì)象操作副本,最后獲取權(quán)限合并,類似git上的PR操作。

    二、什么是原型模式

    原型模式用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并通過(guò)拷貝這些原型創(chuàng)建新的對(duì)象。需要注意的關(guān)鍵字是,新的對(duì)象,類沒(méi)變。.NET在System命名空間中提供了Cloneable接口,其中它提供唯一的方法Clone(),只需要實(shí)現(xiàn)這個(gè)接口就可以完成原型模式了。由于它直接操作內(nèi)存中的二進(jìn)制流,當(dāng)大量操作或操作復(fù)雜對(duì)象時(shí),性能優(yōu)勢(shì)將會(huì)很明顯。

    怎么理解Java設(shè)計(jì)模式的原型模式

    三、原型模式的適用場(chǎng)景

    多用于創(chuàng)建大對(duì)象,或初始化繁瑣的對(duì)象。如游戲中的背景,地圖。web中的畫(huà)布等等

    以下場(chǎng)景適用:

    一是類初始化需要消化非常多的資源,這個(gè)資源包括數(shù)據(jù)、硬件資源等;

    二是通過(guò) new 產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問(wèn)權(quán)限,則可以使用原型模式;

    三是一個(gè)對(duì)象需要提供給其他對(duì)象訪問(wèn),而且各個(gè)調(diào)用者可能都需要修改其值時(shí),可以考慮使用原型模式拷貝多個(gè)對(duì)象供調(diào)用者使用。

    在實(shí)際項(xiàng)目中,原型模式很少單獨(dú)出現(xiàn),一般是和工廠方法模式一起出現(xiàn),通過(guò) clone的方法創(chuàng)建一個(gè)對(duì)象,然后由工廠方法提供給調(diào)用者。

    四、原型模式的實(shí)現(xiàn)

    以簡(jiǎn)歷的復(fù)印來(lái)舉例

    1.淺拷貝實(shí)現(xiàn)

    定義工作經(jīng)歷類

    /// <summary>
    /// 工作經(jīng)歷類
    /// </summary>
    public class WorkExperience
    {
        private string _workDate;
        public string WorkDate
        {
            get { return _workDate; }
            set { _workDate = value; }
        }
         private string _company;
        public string Company
        {
            get { return _company; }
            set { _company = value; }
        }
    }

    定義簡(jiǎn)歷類

    /// <summary>
    /// 簡(jiǎn)歷類
    /// </summary>
    class Resume : ICloneable
    {
        private string name;
        private string sex;
        private string age;
         private WorkExperience work;
         public Resume(string name)
        {
            this.name = name;
            work = new WorkExperience();
        }
         /// <summary>
        /// 設(shè)置個(gè)人信息
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        public void SetPersonalInfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }
         /// <summary>
        /// 設(shè)置工作經(jīng)歷
        /// </summary>
        /// <param name="workDate"></param>
        /// <param name="company"></param>
        public void SetWorkExperience(string workDate, string company)
        {
            work.WorkDate = workDate;
            work.Company = company;
        }
         /// <summary>
        /// 顯示
        /// </summary>
        public void Display()
        {
            Console.WriteLine("{0}{1}{2}", name, sex, age);
            Console.WriteLine("工作經(jīng)歷:{0}{1}", work.WorkDate, work.Company);
        }
         public object Clone()
        {
            //創(chuàng)建當(dāng)前object的淺表副本
            return (object)this.MemberwiseClone();
        }
    }

    客戶端調(diào)用

    static void Main(string[] args)
    {
        Resume a = new Resume("張三");
        a.SetPersonalInfo("男", "30");
        a.SetWorkExperience("2010-2018", "騰訊公司");
         Resume b = (Resume)a.Clone();
        b.SetWorkExperience("2010-2015", "阿里公司");
         Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("女", "18");  c.SetWorkExperience("2010-2015", "百度公司");
         a.Display();
        b.Display();
        c.Display();
         Console.Read();
    }

    結(jié)果

    張三 男 30
    工作經(jīng)歷 2010-2018 騰訊公司
    張三 男 30
    工作經(jīng)歷 2010-2018 騰訊公司
    張三 女 18
    工作經(jīng)歷 2010-2018 騰訊公司

    被復(fù)制對(duì)象的所有變量都含有與原來(lái)的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用都仍然指向原來(lái)的對(duì)象,這就是淺復(fù)制。但是我們可能需要這樣一種需求,要把復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制一遍。比如剛才的例子,我希望a、b、c三個(gè)引用的對(duì)象都是不同的。復(fù)制時(shí)就一變二,二變?nèi)4藭r(shí),我們就要用的方式叫“深復(fù)制”

    2.深拷貝實(shí)現(xiàn)

    深復(fù)制把引用對(duì)象的變量指向復(fù)制過(guò)的新對(duì)象,而不是原來(lái)被引用的對(duì)象

    /// <summary>
    /// 工作經(jīng)歷類
    /// </summary>
    public class WorkExperience:ICloneable
    {
        private string _workDate;
        public string WorkDate
        {
            get { return _workDate; }
            set { _workDate = value; }
        }
         private string _company;
        public string Company
        {
            get { return _company; }
            set { _company = value; }
        }
         public object Clone()
        {
            //創(chuàng)建當(dāng)前object的淺表副本
            return (object)this.MemberwiseClone();
        }
    }
    /// <summary>
    /// 簡(jiǎn)歷類
    /// </summary>
    class Resume : ICloneable
    {
        private string name;
        private string sex;
        private string age;
         private WorkExperience work;
         public Resume(string name)
        {
            this.name = name;
            work = new WorkExperience();
        }
         private Resume(WorkExperience work)
        {
            //提供Clone方法調(diào)用的私有構(gòu)造函數(shù),以便克隆“工作經(jīng)歷”數(shù)據(jù)
            this.work = (WorkExperience)work.Clone();
        }
         /// <summary>
        /// 設(shè)置個(gè)人信息
        /// </summary>
        /// <param name="sex"></param>
        /// <param name="age"></param>
        public void SetPersonalInfo(string sex, string age)
        {
            this.sex = sex;
            this.age = age;
        }
         /// <summary>
        /// 設(shè)置工作經(jīng)歷
        /// </summary>
        /// <param name="workDate"></param>
        /// <param name="company"></param>
        public void SetWorkExperience(string workDate, string company)
        {
            work.WorkDate = workDate;
            work.Company = company;
        }
         /// <summary>
        /// 顯示
        /// </summary>
        public void Display()
        {
            Console.WriteLine("{0}{1}{2}", name, sex, age);
            Console.WriteLine("工作經(jīng)歷:{0}{1}", work.WorkDate, work.Company);
        }
         public object Clone()
        {
            //調(diào)用私有的構(gòu)造方法,讓“工作經(jīng)歷”克隆完成,然后再給這個(gè)簡(jiǎn)歷對(duì)象的相關(guān)字段賦值,
            //最終返回一個(gè)深復(fù)制的簡(jiǎn)歷對(duì)象
            Resume obj = new Resume(this.work);
            obj.name = this.name;
            obj.sex = this.sex;
            obj.age = this.age;
            return obj;
        }
    }

    客戶端調(diào)用代碼一樣

    結(jié)果

    張三 男 30
    工作經(jīng)歷 2010-2018 騰訊公司
    張三 男 30
    工作經(jīng)歷 2010-2015 阿里公司
    張三 女 18
    工作經(jīng)歷 2010-2015 百度公司

    由于在一些特定場(chǎng)合,會(huì)經(jīng)常涉及深復(fù)制和淺復(fù)制,比如說(shuō),數(shù)據(jù)集對(duì)象DataSet,它就有Clone()方法和Copy()方法,Clone()方法用來(lái)復(fù)制DataSet的結(jié)構(gòu),但不復(fù)制DataSet的數(shù)據(jù),實(shí)現(xiàn)了原型模式的淺復(fù)制,

    Copy()方法不但復(fù)制結(jié)構(gòu),還復(fù)制數(shù)據(jù),其實(shí)就是實(shí)現(xiàn)了原型模式的深復(fù)制。

    到此,相信大家對(duì)“怎么理解Java設(shè)計(jì)模式的原型模式”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI