The patterns used in development-visitor patterns

Source: Internet
Author: User

in order to demonstrate the power of the visitor design pattern as much as possible, in this case a developing scenario
For example, developing a group is responsible for the log function, and Group B needs to expose an API to get all the logs.


The code implementation for Group A might look like this:


Public abstract class Orderlog{public string Content {get;set;} Public Orderlog (string content) {content = content;}} public class Placeorderlog:orderlog{public Placeorderlog (String content,string orderedby): Base (content) {Orderedby = Orderedby;} public string Orderedby {Get;set;}} public class Makepaymentlog:orderlog{public Makepaymentlog (String content, String Paymentgateway, String payedby): base (content) {paymentgateway = Paymentgateway; Payedby = Payedby;} public string Paymentgateway {get;set;} public string Payedby {Get;set;}} public class Ordercompletelog:orderlog{public Ordercompletelog (String content, DateTime completedate): Base (content) { Ordercompletedate = completedate;} Public DateTime ordercompletedate {get;set;}} public class Orderlogger{public static Orderlogger Do{get{return new Orderlogger ();}} Public ienumerable<orderlog> Getlogs () {Return to New list<orderlog>{new Placeorderlog ("Place Order Log", " Ordered by "), New Makepaymentlog (" Make Payment log "," PayPal "," Payedby "), NEW Ordercompletelog ("Order complete Log", DateTime.Now)};} 



Group B Usage:
var logs = OrderLogger.Do.GetLogs ();




Group B New requirements come, need a group to do another API, you can add color information to the log entity, such as type a return red, type B back to Green
Group A has two options, add an API, or distribute this responsibility back to group B, since it is clear that the logical B-Group of the display color is more familiar. Of course it is the distribution of responsibility, how it can be distributed, the visitor pattern comes.


1. Add a row to the log base class:
Public abstract T visit<t> (ilogvisitor<t> visitor);




2. Implement it accordingly in the other log subclasses:
public override T visit<t> (Ilogvisitor<t> visitor) {return visitor. Visit (this);}


Why add this method? It is equivalent to opening an entrance to the outside world so that they can come in and pass their information to them to complete the corresponding logic.


3. Give the group B an interface (you can remove the t if there is no return value):
public interface Ilogvisitor<t>{t Visit (placeorderlog log); T Visit (makepaymentlog log); T Visit (Ordercompletelog log);}



Why add this interface?
1. The external visitor implements this interface to get each subclass
2. If the class hierarchy changes, the outside can know
3. External calls do not write large amounts of switch-case or if else bloated judgment logic


Group A completes the work. The next thing to do in Group B is to implement the visitor interface.
The implementation may be like this:


Public enum Orderlogcolor{red,green}public class Orderlogcolorvisitor:ilogvisitor<orderlogcolor>{public Orderlogcolor Visit (Placeorderlog log) {return orderlogcolor.red;} Public Orderlogcolor Visit (makepaymentlog log) {return orderlogcolor.green;} Public Orderlogcolor Visit (ordercompletelog log) {return orderlogcolor.green;}}




Logic is simple and returns different colors for different types. Next is the invocation section:




var logs = OrderLogger.Do.GetLogs ();////show Colorsvar colorvisitor = new Orderlogcolorvisitor (); foreach (var log in logs) {Console.WriteLine (log. Visit<orderlogcolor> (Colorvisitor));}




As you can see, after you get a log collection, the loop process simply calls the visit function, enters the corresponding log class, and in the log class, calls the visit function to complete the visit logic. Execution Result:
Redgreengreen




Next, Group B needs a new task, formatting different strings for different log types.


Then you just need to add another visitor:
public class Orderlogformattedvisitor:ilogvisitor <string> {public string Visit (Placeorderlog log) {return ' This I s Place Order Log formatted information ";} public string Visit (Makepaymentlog log) {return ' This was make payment log formatted information ';} public string Visit (Ordercompletelog log) {return ' This was order complete log formatted information ';}}



Call:
var logs = OrderLogger.Do.GetLogs (), var formatvisitor = new Orderlogformattedvisitor (); foreach (var log in logs) { Console.WriteLine (log. Visit<string> (Formatvisitor));}




Do you see the role of the visitor pattern? It separates the responsibilities and effectively encapsulates the changes. In the above example, Group A is only responsible for the log API, and Group B is responsible for getting the log. In the development will often encounter mutual invocation of the situation, whenever this time, the first consideration of the allocation of responsibilities, the interface to isolate the work, determine the invocation of the portal. This is where the visitor pattern is powerful.


The following is the complete code:


void Main () {var logs = OrderLogger.Do.GetLogs ();////show Colorsvar colorvisitor = new Orderlogcolorvisitor (); foreach ( var log in logs) {Console.WriteLine (log. Visit<orderlogcolor> (Colorvisitor));} Show formatted Logsvar formatvisitor = new Orderlogformattedvisitor (); foreach (var log in logs) {Console.WriteLine ( Log. Visit<string> (Formatvisitor));}} Team A Jobpublic abstract class Orderlog{public string Content {get;set;} Public Orderlog (string content) {content = content;} Public abstract T visit<t> (Ilogvisitor<t> visitor);} public class Placeorderlog:orderlog{public Placeorderlog (String content,string orderedby): Base (content) {Orderedby = Orderedby;} public string Orderedby {get;set;} public override T visit<t> (Ilogvisitor<t> visitor) {return visitor. Visit (this);}} public class Makepaymentlog:orderlog{public Makepaymentlog (String content, String Paymentgateway, String payedby): base (content) {paymentgateway = Paymentgateway; Payedby = Payedby;} public string PaYmentgateway {get;set;} public string Payedby {get;set;} public override T visit<t> (Ilogvisitor<t> visitor) {return visitor. Visit (this);}} public class Ordercompletelog:orderlog{public Ordercompletelog (String content, DateTime completedate): Base (content) { Ordercompletedate = completedate;} Public DateTime ordercompletedate {get;set;} public override T visit<t> (Ilogvisitor<t> visitor) {return visitor. Visit (this);}} public class Orderlogger{public static Orderlogger Do{get{return new Orderlogger ();}} Public ienumerable<orderlog> Getlogs () {Return to New list<orderlog>{new Placeorderlog ("Place Order Log", " Ordered by "), New Makepaymentlog (' Make payment log '," PayPal "," Payedby "), New Ordercompletelog (" Order complete log ", DateTime.Now)};}}  Now Team B want a APIs, return different log color based on different type////team a give team B a visitor interface, Ask them to Implementpublic interface ilogvisitor<t>{t Visit (placeorderlog log); T Visit (Makepaymentlog log); T Visit (Ordercompletelog log);} Team B come out with the Implementationspublic enum Orderlogcolor{red,green}public class Orderlogcolorvisitor:i Logvisitor<orderlogcolor>{public orderlogcolor Visit (placeorderlog log) {return orderlogcolor.red;} Public Orderlogcolor Visit (makepaymentlog log) {return orderlogcolor.green;} Public Orderlogcolor Visit (ordercompletelog log) {return orderlogcolor.green;}} In future////if team B want more, just implement the Ilogvisitor interface////for example:formatted logpublic CLA SS Orderlogformattedvisitor:ilogvisitor <string> {public string Visit (Placeorderlog log) {return ' This was place Ord ER log formatted information ";} public string Visit (Makepaymentlog log) {return ' This was make payment log formatted information ';} public string Visit (Ordercompletelog log) {return ' This was order complete log formatted information ';}} Whats next////whenever team B want, he just add more visitor to accept different logs types returned from TeamA


The patterns used in development-visitor patterns

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.