愚公系列2021年12月 二十三種設(shè)計(jì)模式(二十三)-訪問者模式

      網(wǎng)友投稿 633 2022-05-30

      前言

      設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無疑問,設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的,設(shè)計(jì)模式使代碼編制真正工程化,設(shè)計(jì)模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。項(xiàng)目中合理的運(yùn)用設(shè)計(jì)模式可以完美的解決很多問題,每種模式在現(xiàn)在中都有相應(yīng)的原理來與之對(duì)應(yīng),每一個(gè)模式描述了一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的核心解決方案,這也是它能被廣泛應(yīng)用的原因。

      提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

      一、訪問者模式(Vistor Pattern)

      訪問者模式屬于行為型模式,表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素類的前提下定義作用于這些元素的新操作。

      結(jié)構(gòu)對(duì)象是使用訪問者模式必備條件,而且這個(gè)結(jié)構(gòu)對(duì)象必須存在遍歷自身各個(gè)對(duì)象的方法。

      二、使用步驟

      角色

      1、抽象訪問者(Visitor)

      為該對(duì)象結(jié)構(gòu)中具體元素角色聲明一個(gè)訪問操作接口。該操作接口的名字和參數(shù)標(biāo)識(shí)了發(fā)送訪問請(qǐng)求給具體訪問者的具體元素角色,這樣訪問者就可以通過該元素角色的特定接口直接訪問它;

      2、具體訪問者(Concrete Visitor)

      實(shí)現(xiàn)Visitor聲明的接口;

      3、抽象元素(Element)

      【愚公系列】2021年12月 二十三種設(shè)計(jì)模式(二十三)-訪問者模式

      定義一個(gè)接受訪問操作,它以一個(gè)訪問者(Visitor)作為參數(shù);

      4、具體元素(Concrete Element )

      實(shí)現(xiàn)了抽象元素所定義的接受操作接口;

      5、結(jié)構(gòu)對(duì)象(Object Structure)

      可以提供一個(gè)高層接口以允許訪問者訪問它的元素。

      示例

      命名空間VistorPattern中包含Student學(xué)生基類充當(dāng)抽象元素,它的3個(gè)實(shí)現(xiàn)類Kris、Cherry和Harling分別是我的兒子、女兒和侄女的英文名,它們充當(dāng)具體元素角色。ITeacher接口充當(dāng)抽象訪問者,而Teacher類充當(dāng)具體訪問者?;麅?cè)類Roster充當(dāng)結(jié)構(gòu)對(duì)象。本案例嘗試使用老師根據(jù)花名冊(cè)來進(jìn)行家訪這樣的場(chǎng)景來講述訪問者模式的使用方法。

      public abstract class Student { public string Name { get; protected set; } public Student(string name) { Name = name; } public abstract void Accept(ITeacher teacher); }

      學(xué)生基類Student,代表抽象元素。

      public class Kris : Student { public Kris(string name) : base(name) { } public override void Accept(ITeacher teacher) { teacher.Visit(this); } }

      Kris類,代表某一具體學(xué)生。

      public class Cherry : Student { public Cherry(string name) : base(name) { } public override void Accept(ITeacher teacher) { teacher.Visit(this); } }

      Cherry類,代表某一具體學(xué)生。

      public class Harling : Student { public Harling(string name) : base(name) { } public override void Accept(ITeacher teacher) { teacher.Visit(this); } }

      Harling類,代表某一具體學(xué)生。

      public interface ITeacher { void Visit(Student student); }

      ITeacher接口,代表抽象訪問者。

      public class Teacher : ITeacher { private string _name = null; public Teacher(string name) { _name = name; } public void Visit(Student student) { Console.WriteLine($"Mr.{_name} is going to visit {student.Name}'s home. "); } }

      Teacher類,代表具體訪問者。

      public class Roster { public List Students { get; private set; } public Roster() { Students = new List { new Cherry("Cherry"), new Kris("Kris"), new Harling("Harling") }; } }

      Roster類,代表花名冊(cè),充當(dāng)結(jié)構(gòu)對(duì)象,老師根據(jù)這個(gè)對(duì)象來進(jìn)行家訪。

      public class Program { public static void Main(string[] args) { Roster roster = new Roster(); foreach(var student in roster.Students) { student.Accept(new Teacher("Tony")); } Console.Read(); } }

      以上是調(diào)用方的代碼,以下是這個(gè)案例的輸出結(jié)果:

      Mr.Tony is going to visit Cherry's home. Mr.Tony is going to visit Kris's home. Mr.Tony is going to visit Harling's home.

      總結(jié)

      優(yōu)點(diǎn)

      1、符合單一職責(zé)原則,凡是適用訪問者模式的場(chǎng)景中,元素類中需要封裝在訪問者中的操作必定是與元素類本身關(guān)系不大且是易變的操作,使用訪問者模式一方面符合單一職責(zé)原則,另一方面,因?yàn)楸环庋b的操作通常來說都是易變的,所以當(dāng)發(fā)生變化時(shí),就可以在不改變?cè)仡惐旧淼那疤嵯?,?shí)現(xiàn)對(duì)變化部分的擴(kuò)展;

      2、擴(kuò)展性良好,元素類可以通過接受不同的訪問者來實(shí)現(xiàn)對(duì)不同操作的擴(kuò)展。

      缺點(diǎn)

      1、增加新的元素類變得困難,每增加一個(gè)新的元素意味著要在抽象訪問者角色中增加一個(gè)新的抽象操作,并在每一個(gè)具體訪問者類中添加相應(yīng)的具體操作。

      使用場(chǎng)景

      1、一個(gè)對(duì)象結(jié)構(gòu)包含很多類對(duì)象,它們有不同的接口,而你想對(duì)這些對(duì)象實(shí)施一些依賴于其具體類的操作;

      2、需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對(duì)象的類。Visitor模式使得你可以將相關(guān)的操作集中起來 定義在一個(gè)類中;

      3、當(dāng)該對(duì)象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用Visitor模式讓每個(gè)應(yīng)用僅包含需要用到的操作;

      4、定義對(duì)象結(jié)構(gòu)的類很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對(duì)象結(jié)構(gòu)類需要重定義對(duì)所有訪問者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類經(jīng)常改變,那么可能還是在這些類中定義這些操作較好。

      面向?qū)ο缶幊?/p>

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:什么是 Kafka Streams 以及它們是如何實(shí)現(xiàn)的?
      下一篇:HDFS 命令:管理 HDFS 的 Hadoop Shell 命令
      相關(guān)文章
      亚洲免费在线观看视频| 亚洲精品成人av在线| 亚洲欧洲日产国码www| 国产亚洲精品a在线观看app| 国产av无码专区亚洲av果冻传媒| 精品无码专区亚洲| 国产精品亚洲一区二区三区久久 | 在线精品亚洲一区二区小说| 亚洲精品网站在线观看不卡无广告 | 亚洲人成图片网站| 亚洲av无码一区二区三区观看| 精品日韩亚洲AV无码一区二区三区 | 亚洲精品综合久久| 久久久青草青青国产亚洲免观 | 国产亚洲精品AAAA片APP| 欧洲亚洲综合一区二区三区| 亚洲av无码不卡私人影院| 亚洲国产成人精品91久久久| 2048亚洲精品国产| 久久亚洲国产中v天仙www| 亚洲AV无码乱码国产麻豆| 亚洲国产女人aaa毛片在线| 亚洲欧洲日韩国产综合在线二区| 一区二区三区亚洲| 亚洲国产成人久久三区| 99999久久久久久亚洲| 亚洲精品无码一区二区| 亚洲AV综合色区无码一二三区 | 亚洲免费一区二区| 国产亚洲精品一品区99热| 亚洲AV美女一区二区三区| 亚洲黄色三级网站| 亚洲精品国产精品国自产网站 | 亚洲综合在线视频| 亚洲一区欧洲一区| 日本中文一区二区三区亚洲| 中文字幕亚洲综合久久男男| 亚洲不卡中文字幕无码| 亚洲精品美女久久久久| 在线观看亚洲AV每日更新无码| 综合一区自拍亚洲综合图区|