日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

北风设计模式课程---访问者模式(Visitor)

發布時間:2023/12/20 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 北风设计模式课程---访问者模式(Visitor) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

北風設計模式課程---訪問者模式(Visitor)

一、總結

一句話總結:

設計模式是日常問題的經驗總結方案,所以學好設計模式對日常出現的問題可以有很好的解決。
訪問者設計模式有點神似 抽象工廠模式,都是增加一個維度很容易,增加另外一個維度很麻煩

?

1、訪問者模式實例?

1、在患者就醫時,醫生會根據病情開具處方單,很多醫院都會存在以下這個流程:劃價人員拿到處方單之后根據藥品名稱和數量計算總價,而藥房工作人員根據藥品名稱和數量準備藥品,
2、在軟件開發中,有時候也需要處理像處方單這樣的集合對象結構,在該對象結構中存儲了多個不同類型的對象信息,而且對同一對象結構中的元素的操作方式并不唯一,可能需要提供多種不同的處理方式。在設計模式中,有一種模式可以滿足上述要求,其模式動機就是以不同的方式操作復雜對象結構,該模式就是訪問者模式。

?

2、訪問者模式簡介?

1、訪問者模式是一種較為復雜的行為型模式,它包含【訪問者和被訪問元素】兩個主要組成部分,這些被訪問的元素通常具有不同的類型,且【不同的訪問者可以對它們進行不同的訪問操作】。例如:【處方單中的各種藥品信息就是被訪問的元素,而劃價人員和藥房工作人員就是訪問者】。訪問者模式可以使得用戶在不修改現有系統的情況下擴展系統的功能,為這些不同類型的元素增加新的操作。
2、提供一個作用于某對象結構中的各元素的操作表示,它使得可以在不改變各元素的類的前提下定義作用于這些元素的新操作。

?

?

3、訪問者模式主要角色?

1、Visitor(抽象訪問者)/ConcreteVisitor(具體訪問者):抽象訪問者為對象結構中每一個具體元素類ConcreteElement聲明一個訪問操作,從這個操作的名稱或參數類型可以清楚知道需要訪問的具體元素的類型,具體訪問者則需要實現這些操作方法,定義對這些元素的訪問操作。具體訪問者實現了抽象訪問者聲明的方法,每一個操作作用于訪問對象結構中一種類型的元素。
2、Element(抽象元素)/ConcreteElement(具體元素):一般是一個抽象類或接口,定義一個Accept方法,該方法通常以一個抽象訪問者作為參數。具體元素實現了Accept方法,在Accept方法中調用訪問者的訪問方法以便完成一個元素的操作。
3、ObjectStructure(對象結構):對象結構是一個元素的集合,用于存放元素對象,且提供便利其內部元素的方法。


  (1)Visitor(抽象訪問者):抽象訪問者為對象結構中每一個具體元素類ConcreteElement聲明一個訪問操作,從這個操作的名稱或參數類型可以清楚知道需要訪問的具體元素的類型,具體訪問者則需要實現這些操作方法,定義對這些元素的訪問操作。
  (2)ConcreteVisitor(具體訪問者):具體訪問者實現了抽象訪問者聲明的方法,每一個操作作用于訪問對象結構中一種類型的元素。
  (3)Element(抽象元素):一般是一個抽象類或接口,定義一個Accept方法,該方法通常以一個抽象訪問者作為參數。
  (4)ConcreteElement(具體元素):具體元素實現了Accept方法,在Accept方法中調用訪問者的訪問方法以便完成一個元素的操作。
  (5)ObjectStructure(對象結構):對象結構是一個元素的集合,用于存放元素對象,且提供便利其內部元素的方法。

?

4、訪問者模式 實現 重構OA系統員工數據 的角色實例?

1、FinanceDepartment表示財務部,HRDepartment表示人力資源部,它們充當具體訪問者的角色,其抽象父類Department充當抽象訪問者角色;
2、EmployeeList充當對象結構,用于存儲員工列表;
3、FullTimeEmployee表示全職員工,PartTimeEmployee表示兼職員工,它們充當具體元素角色,而其父類IEmployee(這里實現形式是interface)充當抽象元素角色。

?

5、訪問者模式中的對象結構類示例?

|||-begin

/// <summary>/// 對象結構類:EmployeeList/// </summary>public class EmployeeList{private IList<IEmployee> empList = new List<IEmployee>();public void AddEmployee(IEmployee emp){this.empList.Add(emp);}public void Accept(Department handler){foreach (var emp in empList){emp.Accept(handler);}}

|||-end

private IList<IEmployee> empList = new List<IEmployee>();:用于存儲員工列表

?

6、訪問模式的主要優缺點?

1、增加新的訪問操作十分方便,不痛不癢 => 符合開閉原則
2、增加新的元素類很困難,需要在每一個訪問者類中增加相應訪問操作代碼 => 違背了開閉原則

?

7、適合多維的設計模式?

訪問者設計模式,抽象工廠設計模式,橋接模式,外觀模式

?

8、訪問者模式 主要優點?

(1)增加新的訪問操作十分方便,不痛不癢 => 符合開閉原則
(2)將有關元素對象的訪問行為集中到一個訪問者對象中,而不是分散在一個個的元素類中,類的職責更加清晰 => 符合單一職責原則

?

9、訪問者模式 主要缺點?

(1)增加新的元素類很困難,需要在每一個訪問者類中增加相應訪問操作代碼 => 違背了開閉原則
(2)元素對象有時候必須暴露一些自己的內部操作和狀態,否則無法供訪問者訪問 => 破壞了元素的封裝性

?

10、訪問者模式 應用場景?

(1)一個對象結構包含多個類型的對象,希望對這些對象實施一些依賴其具體類型的操作。=> 不同的類型可以有不同的訪問操作
(2)對象結構中對象對應的類很少改變 很少改變 很少改變(重要的事情說三遍),但經常需要在此對象結構上定義新的操作。

?

11、訪問者模式實例?

- M公司開發部想要為某企業開發一個OA系統,在該OA系統中包含一個員工信息管理子系統,該企業包括正式員工和臨時工,每周HR部門和財務部等部門需要對員工數據進行匯總,匯總數據包括員工工作時間、員工工資等等。該企業的基本制度如下:
- (1)正式員工(Full time Employee)每周工作時間為40小時,不同級別、不同部門的員工每周基本工資不同;如果超過40小時,超出部分按照100元/小時作為加班費;如果少于40小時,所缺時間按照請假處理,請假鎖扣工資以80元/小時計算,直到基本工資扣除到0為止。除了記錄實際工作時間外,HR部需要記錄加班時長或請假時長,作為員工平時表現的一項依據。
- (2)臨時員工(Part time Employee)每周工作時間不固定,基本工資按照小時計算,不同崗位的臨時工小時工資不同。HR部只需要記錄實際工作時間。
- HR人力資源部和財務部工作人員可以根據各自的需要對員工數據進行匯總處理,HR人力資源部負責匯總每周員工工作時間,而財務部負責計算每周員工工資。

?

?

二、設計模式的征途—16.訪問者(Visitor)模式

轉自或參考:設計模式的征途—16.訪問者(Visitor)模式
https://www.cnblogs.com/edisonchou/p/7247990.html

在患者就醫時,醫生會根據病情開具處方單,很多醫院都會存在以下這個流程:劃價人員拿到處方單之后根據藥品名稱和數量計算總價,而藥房工作人員根據藥品名稱和數量準備藥品,如下圖所示。

在軟件開發中,有時候也需要處理像處方單這樣的集合對象結構,在該對象結構中存儲了多個不同類型的對象信息,而且對同一對象結構中的元素的操作方式并不唯一,可能需要提供多種不同的處理方式。在設計模式中,有一種模式可以滿足上述要求,其模式動機就是以不同的方式操作復雜對象結構,該模式就是訪問者模式。

訪問者模式(Visitor)學習難度:★★★★☆使用頻率:★☆☆☆☆

一、OA系統員工數據匯總設計

1.1 需求背景

Background:M公司開發部想要為某企業開發一個OA系統,在該OA系統中包含一個員工信息管理子系統,該企業包括正式員工和臨時工,每周HR部門和財務部等部門需要對員工數據進行匯總,匯總數據包括員工工作時間、員工工資等等。該企業的基本制度如下:

(1)正式員工(Full time Employee)每周工作時間為40小時,不同級別、不同部門的員工每周基本工資不同;如果超過40小時,超出部分按照100元/小時作為加班費;如果少于40小時,所缺時間按照請假處理,請假鎖扣工資以80元/小時計算,直到基本工資扣除到0為止。除了記錄實際工作時間外,HR部需要記錄加班時長或請假時長,作為員工平時表現的一項依據。

(2)臨時員工(Part time Employee)每周工作時間不固定,基本工資按照小時計算,不同崗位的臨時工小時工資不同。HR部只需要記錄實際工作時間。

HR人力資源部和財務部工作人員可以根據各自的需要對員工數據進行匯總處理,HR人力資源部負責匯總每周員工工作時間,而財務部負責計算每周員工工資。

1.2 初始設計

  M公司開發人員針對需求,提出了一個初始的解決方案,其核心代碼如下:

public class EmployeeList{// 員工集合private IList<Employee> empList = new List<Employee>();// 增加員工public void AddEmployee(Employee emp){this.empList.Add(emp);}// 處理員工數據public void Handle(string deptName){if (deptName.Equals("財務部")){foreach (var emp in empList){if (emp.GetType().Equals("FullTimeEmployee")){Console.WriteLine("財務部處理全職員工數據!");}else{Console.WriteLine("財務部處理兼職員工數據!");}}}else if (deptName.Equals("人力資源部")){foreach (var emp in empList){if (emp.GetType().Equals("FullTimeEmployee")){Console.WriteLine("人力資源部處理全職員工數據!");}else{Console.WriteLine("人力資源部處理兼職員工數據!");}}}}}

  不難發現,該解決方案存在以下問題:

  (1)EmployeeList類非常龐大,承擔了過多的職責,既不便于代碼復用,也不便于系統擴展,違背了單一職責原則。

  (2)包含了大量的if-else語句,測試和維護的難度增大。

  (3)如果要新增一個部門來操作員工數據集合,那么不得不修改EmployeeList類的源代碼,違背了開閉原則。

  訪問者模式是一個可以考慮用來解決的方案,它可以在一定程度上解決上述問題(大部分問題)。

二、訪問者模式概述

2.1 訪問者模式簡介

  訪問者模式是一種較為復雜的行為型模式,它包含訪問者和被訪問元素兩個主要組成部分,這些被訪問的元素通常具有不同的類型,且不同的訪問者可以對它們進行不同的訪問操作。例如:處方單中的各種藥品信息就是被訪問的元素,而劃價人員和藥房工作人員就是訪問者。訪問者模式可以使得用戶在不修改現有系統的情況下擴展系統的功能,為這些不同類型的元素增加新的操作。

訪問者(Visitor)模式:提供一個作用于某對象結構中的各元素的操作表示,它使得可以在不改變各元素的類的前提下定義作用于這些元素的新操作。訪問者模式是一種對象行為型模式。

2.2 訪問者模式結構

  訪問者模式結構圖中包含以下5個角色:

  (1)Visitor(抽象訪問者):抽象訪問者為對象結構中每一個具體元素類ConcreteElement聲明一個訪問操作,從這個操作的名稱或參數類型可以清楚知道需要訪問的具體元素的類型,具體訪問者則需要實現這些操作方法,定義對這些元素的訪問操作。

  (2)ConcreteVisitor(具體訪問者):具體訪問者實現了抽象訪問者聲明的方法,每一個操作作用于訪問對象結構中一種類型的元素。

  (3)Element(抽象元素):一般是一個抽象類或接口,定義一個Accept方法,該方法通常以一個抽象訪問者作為參數。

  (4)ConcreteElement(具體元素):具體元素實現了Accept方法,在Accept方法中調用訪問者的訪問方法以便完成一個元素的操作。

  (4)ObjectStructure(對象結構):對象結構是一個元素的集合,用于存放元素對象,且提供便利其內部元素的方法。

三、重構OA系統員工數據匯總

3.1 重構后的設計結構

  在上圖中,FinanceDepartment表示財務部,HRDepartment表示人力資源部,它們充當具體訪問者的角色,其抽象父類Department充當抽象訪問者角色;EmployeeList充當對象結構,用于存儲員工列表;FullTimeEmployee表示全職員工,PartTimeEmployee表示兼職員工,它們充當具體元素角色,而其父類IEmployee(這里實現形式是interface)充當抽象元素角色。

3.2 具體代碼實現

  (1)抽象元素=>IEmployee

/// <summary>/// 抽象元素類:Employee/// </summary>public interface IEmployee{void Accept(Department handler);}

  (2)具體元素=>FullTimeEmployee,PartTimeEmployee

/// <summary>/// 具體元素類:FullTimeEmployee/// </summary>public class FullTimeEmployee : IEmployee{public string Name { get; set; }public double WeeklyWage { get; set; }public int WorkTime { get; set; }public FullTimeEmployee(string name, double weeklyWage, int workTime){this.Name = name;this.WeeklyWage = weeklyWage;this.WorkTime = workTime;}public void Accept(Department handler){handler.Visit(this);}}/// <summary>/// 具體元素類:PartTimeEmployee/// </summary>public class PartTimeEmployee : IEmployee{public string Name { get; set; }public double HourWage { get; set; }public int WorkTime { get; set; }public PartTimeEmployee(string name, double hourWage, int workTime){this.Name = name;this.HourWage = hourWage;this.WorkTime = workTime;}public void Accept(Department handler){handler.Visit(this);}}

  (3)對象結構=>EmployeeList

/// <summary>/// 對象結構類:EmployeeList/// </summary>public class EmployeeList{private IList<IEmployee> empList = new List<IEmployee>();public void AddEmployee(IEmployee emp){this.empList.Add(emp);}public void Accept(Department handler){foreach (var emp in empList){emp.Accept(handler);}}

  (4)抽象訪問者=>Department

/// <summary>/// 抽象訪問者類:Department/// </summary>public abstract class Department{// 聲明一組重載的訪問方法,用于訪問不同類型的具體元素public abstract void Visit(FullTimeEmployee employee);public abstract void Visit(PartTimeEmployee employee);}

  (5)具體訪問者=>FinanceDepartment,HRDepartment

/// <summary>/// 具體訪問者類:FinanceDepartment/// </summary>public class FinanceDepartment : Department{// 實現財務部對兼職員工數據的訪問public override void Visit(PartTimeEmployee employee){int workTime = employee.WorkTime;double hourWage = employee.HourWage;Console.WriteLine("臨時工 {0} 實際工資為:{1} 元", employee.Name, workTime * hourWage);}// 實現財務部對全職員工數據的訪問public override void Visit(FullTimeEmployee employee){int workTime = employee.WorkTime;double weekWage = employee.WeeklyWage;if (workTime > 40){weekWage = weekWage + (workTime - 40) * 50;}else if (workTime < 40){weekWage = weekWage - (40 - workTime) * 80;if (weekWage < 0){weekWage = 0;}}Console.WriteLine("正式員工 {0} 實際工資為:{1} 元", employee.Name, weekWage);}}/// <summary>/// 具體訪問者類:HRDepartment/// </summary>public class HRDepartment : Department{// 實現人力資源部對兼職員工數據的訪問public override void Visit(PartTimeEmployee employee){int workTime = employee.WorkTime;Console.WriteLine("臨時工 {0} 實際工作時間為:{1} 小時", employee.Name, workTime);}// 實現人力資源部對全職員工數據的訪問public override void Visit(FullTimeEmployee employee){int workTime = employee.WorkTime;Console.WriteLine("正式員工 {0} 實際工作時間為:{1} 小時", employee.Name, workTime);if (workTime > 40){Console.WriteLine("正式員工 {0} 加班時間為:{1} 小時", employee.Name, workTime - 40);}else if (workTime < 40){Console.WriteLine("正式員工 {0} 請假時間為:{1} 小時", employee.Name, 40 - workTime);}}}

  (6)客戶端調用與測試

public class Program{public static void Main(string[] args){EmployeeList empList = new EmployeeList();IEmployee fteA = new FullTimeEmployee("梁思成", 3200.00, 45);IEmployee fteB = new FullTimeEmployee("徐志摩", 2000, 40);IEmployee fteC = new FullTimeEmployee("梁徽因", 2400, 38);IEmployee fteD = new PartTimeEmployee("方鴻漸", 80, 20);IEmployee fteE = new PartTimeEmployee("唐宛如", 60, 18);empList.AddEmployee(fteA);empList.AddEmployee(fteB);empList.AddEmployee(fteC);empList.AddEmployee(fteD);empList.AddEmployee(fteE);Department dept = AppConfigHelper.GetDeptInstance() as Department;if (dept != null){empList.Accept(dept);}Console.ReadKey();}}

  其中,AppConfigHelper用于從配置文件中獲得具體訪問者實例,配置文件如下:

<?xml version="1.0" encoding="utf-8" ?> <configuration><appSettings><add key="DeptName" value="Manulife.ChengDu.DesignPattern.Visitor.HRDepartment, Manulife.ChengDu.DesignPattern.Visitor" /></appSettings> </configuration>

  AppConfigHelper的具體代碼如下:

public class AppConfigHelper{public static string GetDeptName(){string factoryName = null;try{factoryName = System.Configuration.ConfigurationManager.AppSettings["DeptName"];}catch (Exception ex){Console.WriteLine(ex.Message);}return factoryName;}public static object GetDeptInstance(){string assemblyName = AppConfigHelper.GetDeptName();Type type = Type.GetType(assemblyName);var instance = Activator.CreateInstance(type);return instance;}} View Code

  編譯運行后的結果如下:

  

  如果需要更換具體訪問者類,無須修改源代碼,只需要修改一下配置文件。例如這里將訪問者由人力資源部更改為財務部:

<?xml version="1.0" encoding="utf-8" ?> <configuration><appSettings><add key="DeptName" value="Manulife.ChengDu.DesignPattern.Visitor.FinanceDepartment, Manulife.ChengDu.DesignPattern.Visitor" /></appSettings> </configuration>

?  此時再次運行則會得到以下結果:

  

  可以看出,如果我們要在系統中新增訪問者,那么無需修改源代碼,只需新增一個新的具體訪問者類即可,從這一點看,訪問者模式符合開閉原則。

  但是,如果我們要在系統中新增具體元素,比如新增一個新的員工類型為“退休人員”,由于原系統并未提供相應的訪問接口,因此必須對原有系統進行修改。所以,從新增新的元素來看,訪問者模式違背了開閉原則

  因此,訪問者模式與抽象工廠模式類似,對于開閉原則的支持具有“傾斜”性,可以方便地新增訪問者,但是添加新的元素較為麻煩。

四、訪問者模式總結

4.1 主要優點

  (1)增加新的訪問操作十分方便,不痛不癢 => 符合開閉原則

  (2)將有關元素對象的訪問行為集中到一個訪問者對象中,而不是分散在一個個的元素類中,類的職責更加清晰 =>?符合單一職責原則

4.2 主要缺點

  (1)增加新的元素類很困難,需要在每一個訪問者類中增加相應訪問操作代碼 => 違背了開閉原則

  (2)元素對象有時候必須暴露一些自己的內部操作和狀態,否則無法供訪問者訪問 => 破壞了元素的封裝性

4.3?應用場景

  (1)一個對象結構包含多個類型的對象,希望對這些對象實施一些依賴其具體類型的操作。=> 不同的類型可以有不同的訪問操作

  (2)對象結構中對象對應的類很少改變?很少改變 很少改變(重要的事情說三遍),但經常需要在此對象結構上定義新的操作。

參考資料

  

  劉偉,《設計模式的藝術—軟件開發人員內功修煉之道》

?

轉載于:https://www.cnblogs.com/Renyi-Fan/p/11105295.html

總結

以上是生活随笔為你收集整理的北风设计模式课程---访问者模式(Visitor)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中文字幕乱码亚洲无线三区 | 亚洲欧美在线一区二区 | 狠狠爱视频| 黄色网址大全免费 | 欧美午夜一区二区 | 欧美 亚洲 另类 偷偷 自拍 | 玖玖在线观看 | 一级做a在线观看 | 网爆门在线 | jjzz日本女人 | 日韩精品无码一区二区三区 | 国产精品xxx在线观看www | 久久三级 | 日韩av在线直播 | 婷婷久久一区 | 亚洲成人第一 | 她也啪在线视频 | 日日夜夜中文字幕 | 一区二区免费在线播放 | 女人下面喷水视频 | 久久久久久久久久久影院 | 男人天堂手机在线 | 在线能看的av网站 | 日批视频在线播放 | 成人羞羞国产免费 | 波多野吉衣在线视频 | 亚洲污片| 可以看污的网站 | 波多野结衣一区二区三区四区 | 国产精品高潮呻吟久久 | 老色批av | 色av资源| 国产精品久久久久久久久毛片 | 日本a级一区 | 男女激情大尺度做爰视频 | 天天干夜夜操视频 | 亚洲欧洲视频在线观看 | 亚洲涩涩图 | 美女色综合| 91爱爱爱爱 | 男女啪啪无遮挡 | 人与嘼交av免费 | 无码国产精品一区二区免费16 | 国产高清视频网站 | 亚洲狼人综合网 | 欧美涩色 | 婷婷亚洲视频 | 国产二级视频 | 国产精品一区二区免费看 | 国产内射老熟女aaaa∵ | 免费国产一区二区 | 亚洲五月婷婷 | 综合在线一区 | 日日夜夜拍| 亚洲男人天堂久久 | 成人福利网站在线观看 | 日韩xx视频| 久久青青草原亚洲av无码麻豆 | 人人艹人人爽 | 特级av片| 久久一级免费视频 | 夜间福利在线 | 中国女人av | 天天操天天干天天 | 国产精品久久久久久精 | 日韩精品高清在线观看 | 成年人在线观看av | 国产一区视频在线播放 | 日本视频网 | 美女一区二区三区 | 丰满双乳秘书被老板狂揉捏 | www视频在线观看 | 成人片黄网站久久久免费 | 无码人妻丰满熟妇精品区 | 国产欧美日韩精品区一区二污污污 | 91射射| 国产一区福利 | 亚洲美女屁股眼交3 | 又欲又污又肉又黄短文 | 亚洲丁香色| 97插插插| 国产在线一区二区三区四区 | 中文字幕一区二区不卡 | 在线免费毛片 | 91在线精品李宗瑞 | 精品欧美一区二区三区免费观看 | 欧美一区二区三区粗大 | 久久久免费观看视频 | 精品视频大全 | 久久精品国产精品亚洲毛片 | 99精品视频99 | 国产精品一级片在线观看 | 久久久久久九九 | 欧美黑大粗| 五月婷婷视频 | 38在线视频 | 免费看成人| 少妇在军营h文高辣 | 六月色|