First, the Interpreter mode
Given a language, define a representation of its grammar and define an interpreter that interprets the sentences in the language using that representation.
Apply: When there is a language that needs to be interpreted and executed, and you can represent the sentence in that language as an abstract syntax tree, you can use the interpreter pattern.
Cons: The interpreter pattern defines at least one class for each rule in the grammar, so grammars that contain many rules can be difficult to manage and maintain. It is recommended that when the grammar is very complex, other counts such as the parser or compiler generator are used to handle it.
Abstract classabstractexpression { Public Abstract voidinterpret (context context); } //Terminator-expression classterminalexpression:abstractexpression { Public Override voidinterpret (context context) {Console.WriteLine ("Terminal Interpreter"); } } //non-terminator expressions that require a specific non-Terminator expression class for each rule in the grammar classnonterminalexpression:abstractexpression { Public Override voidinterpret (context context) {Console.WriteLine ("non-terminal interpreter"); } }
classContext {Private stringinput; Public stringInput {Get{returninput;} Set{input =value;} } Private stringoutput; Public stringOutput {Get{returnoutput;} Set{output =value;} } }
Static voidMain (string[] args) {Context Context=NewContext (); IList<AbstractExpression> list =NewList<abstractexpression>(); List. ADD (Newterminalexpression ()); List. ADD (Newnonterminalexpression ()); List. ADD (Newterminalexpression ()); List. ADD (Newterminalexpression ()); foreach(Abstractexpression expinchlist) {exp. Interpret (context); } console.read (); }
Second, the iterator mode
Provides a way to sequentially access individual elements of an aggregated object without exposing an internal representation of the object, such as foreach. Ieumerator supports simple iterative interfaces to non-generic collections.
Apply: You should consider using the iterator pattern when you need to access a clustered object, and regardless of what these objects need to traverse.
Key idea: the access and traversal of the list is detached from the list object and placed into an iterator object, which defines an interface to access the list element. The iterator object is responsible for tracking the current element and knowing which elements have been traversed.
Abstract classIterator {//define the abstract methods of start, next, end of judgment, current object, unified interface Public Abstract ObjectFirst (); Public Abstract ObjectNext (); Public Abstract BOOLIsDone (); Public Abstract ObjectCurrentItem (); } classConcreteiterator:iterator {//defines a specific clustered object Privateconcreteaggregate Aggregate; Private intCurrent =0; //when initializing, the specific clustered object is passed in PublicConcreteiterator (concreteaggregate aggregate) { This. aggregate =aggregate; } //get the first object to gather Public Override ObjectFirst () {returnaggregate[0]; } //get the next object that is clustered Public Override ObjectNext () {ObjectRET =NULL; Current++; if(Current <aggregate. Count) {ret=Aggregate[current]; } returnret; } //returns the current clustered object Public Override ObjectCurrentItem () {returnAggregate[current]; } //determines whether the current traversal is to the end and returns true to the end Public Override BOOLIsDone () {returnCurrent >= aggregate. Count?true:false; } } classConcreteiteratordesc:iterator {Privateconcreteaggregate Aggregate; Private intCurrent =0; PublicConcreteiteratordesc (concreteaggregate aggregate) { This. aggregate =aggregate; Current= aggregate. Count-1; } Public Override ObjectFirst () {returnAggregate[aggregate. Count-1]; } Public Override ObjectNext () {ObjectRET =NULL; Current--; if(Current >=0) {ret=Aggregate[current]; } returnret; } Public Override ObjectCurrentItem () {returnAggregate[current]; } Public Override BOOLIsDone () {returnCurrent <0?true:false; } }
//Creating Iterators Abstract classAggregate { Public AbstractIterator createiterator (); } classConcreteaggregate:aggregate {//declares a list generic variable to hold the aggregated object Privateilist<Object> items =Newlist<Object>(); Public OverrideIterator Createiterator () {return NewConcreteiterator ( This); } //returns the total number of aggregates Public intCount {Get{returnitems. Count; } } //declaring an indexer Public Object This[intIndex] { Get{returnItems[index];} Set{items. Insert (index, value); } } }
Static voidMain (string[] args) {Concreteaggregate a=Newconcreteaggregate (); a[0] ="Big Bird"; a[1] ="Side Dishes"; a[2] ="baggage"; a[3] ="Foreigner"; a[4] ="internal staff of public transport"; a[5] ="thief"; Iterator I=NewConcreteiterator (a); Objectitem =I.first (); while(!I.isdone ()) {Console.WriteLine ("{0} please buy a ticket!", I.currentitem ()); I.next (); } console.read (); }
Iii. Summary
The last case in the book is mainly about the design ideas, relatively simple, in the actual operation of the problems encountered far more complex than this. Read many times just to have a systematic understanding of these design patterns, use or need to ingenious through the actual project.
The books in Appendix B can be learned, sometimes book publishing time does not mean that there is no reading meaning, and the principle involved is now dependent on the development platform to do the process of the key ideas.
13, the behavior mode interpreter, the iterator-----"The Liar design Pattern"