elasticsearch入門系列">elasticsearch入門系列
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)
定義一個(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
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)容。