Chapter 5 Behavior mode behavior pattern involves the allocation of algorithms and inter-object responsibilities. Behavior mode not only describes the objects or classes of the object, but also describes the communication mode between them. These patterns scored a complex control flow that was difficult to track at runtime. They turn your attention from the control flow to the contact information between the objects. Behavioral mode uses the inheritance mechanism to dispatch behavior between class. This chapter includes two such modes. Among them, TE m P L A T EM E T H O D (5. 1 0) is simpler and common. The template method is an abstract definition of an algorithm that gradually defines the algorithm, and each step is called an abstract operation or an original operation, and the subclass defines the abstraction operation to implement the algorithm. Another behavioral class mode is I N T E R P R E T E R (5. 3). It expresses a grammar as a class level and implements an interpreter as an operation on the instance of these classes. Behavioral object mode uses object composite instead of inheritance. Some behavior object patterns describe how a set of objects work collaborate with each other to complete any objects that cannot be completed separately. An important issue here is how the peer objects understand each other. Peer objects can maintain explicitly reference to each other, but then increase their coupling. In extreme cases, every object is to understand all other objects. ME E D i a T O R (5. 5) Introduces a ME E D i a T O R object between peer objects to avoid this. M e D i a t O r provides an indirectity required for loosely coupled. Chain of Responsibility (5.1) provides loose coupling. It allows you to send a request to an object through a candidate object chain. Any candidate can respond to the corresponding request based on the runtime situation. The number of candidates is arbitrary, you can decide which candidates participate in the chain at runtime. O b S e r v E R (5. 7) mode defines and maintains dependencies between objects. Examples of typical O b S e R v E r are model / view / controllers in SmallTalk, where all views of the model are notified once the state changes. Other behavior object patterns often package behavior into an object and assign the request to it. S T R A T E G Y (5. 9) mode is packaged in the object, which can easily specify and change an algorithm used by an object. C O m M M M M M M M M M M M M M M M M M M M M M M A N D (5) Mode will be encapsulated in the object so that it can be passed as a parameter or stored in a historical list or otherwise use. The S t a t e (5. 8) mode encapsulates the status of an object, so that when the status object of this object changes, the object can change its behavior. VI S i T O R (5. 11) The package is distributed between multiple classes, and I T E R A T O R (5. 4) is abstracted to access and traverse an object in a collection. 5.1 Chain of Responsibility - Object Behavior Type 1. It is intended to have multiple objects to handle requests, thereby avoiding coupling relationships between requesting senders and recipients. Connect these objects into a chain and deliver the request along this chain until there is an object to process it. 2. Motivation considers the help mechanism related to the context in a graphical user interface. The user can get help information on either part of the interface, which is the help depend on which part of the interface is and the context. For example, the help information of the buttons in the dialog may be different from the buttons similar to the main window. If there is no specific help information for that section, the help system should display a more general help information about the current context - such as, the entire dialog. It is therefore naturally, and the help information should be organized from the most special to the most common order according to the universality (G E N E R A L I T Y). Moreover, it is obvious that there is an object in these user interface objects to handle help requests; as the object depends on the context and how the available help specifically. The problem here is that the object of submitting the help request (such as button) is not clearly known who is the object that ends help.
We have to have a way to submit objects that the help request with objects that may provide help information (D E C O U P L E). CHAIN OFR E S P O N S I B i L i t y mode tells us what should be done. The idea of this mode is to process a request for multiple objects to decouple the sender and the recipient. This request is passed along the object chain until one of the objects processes it, as shown in the following figure. Starting from the first object, the object received in the chain either processes it, or forwards the next candidate in the chain. The object submitted is not clearly known which object will handle it - we say that the request has an implicit recipient (Implicit Receiver). Assume that the user clicks on a button window component labeled "P R I n t", and the button is included in an example of P R i N T D i a L O G, which knows the application object it belongs (see the front object block diagram). The following interactive block diagram illustrates how to help request how to pass along the chain: In this example, neither APRINTBUTTON is not APRINTDIALOG to process the request; it has been passed to A N a pl i c a t i o n, Anapplication handles it or ignore it. Customers submitted are not directly referenced to the object that eventually responds. To revolute along the chain and ensure that the recipient is implicit (I m P L i C I T), each of the objects on the chain has a consistent processing request and access the links on the chain successor. For example, a help system defines an HE E L P h a n d L e-class with corresponding HandleHelp operations. Helphandler can be a parent class of all candidate objects, or it can be defined as a mixed (M i x I n) class. This way you want to deal with the class that helps the request, you can use the Helphandler as a parent class, as shown in the following page. Buttons, dialogs, and application classes use Helphandler operation to handle help requests. The HANDLEHELP operation of H e l p h a n d l e r is to forward the request to the successor. Subclass can define this operation to provide assistance in an appropriate situation; otherwise they can forward the request using the default implementation. 3. Applicability Use the Responsibility chain under the following conditions: • A plurality of objects can handle a request, which object processes the request runtime automatically determines. • You want to submit a request to one of multiple objects without explicitly designating the recipient. • The collection of objects that can be processed should be manually specified. 4. Structure A typical object structure may be shown below: 5. Participants • H A N D L E R (such as HE E L P H a N D L E R) - Defines an interface for processing requests. - (Optional) Realize the backchain. • C O N C R e t e h A n d l e r (such as P R I N N T D T T O N and P R I N T D i a L O G) - the request it is responsible. - Access to its successor. - If you can process the request, it processes; otherwise forward the request to its successor. • C L i e n t-to the specific processor (C O N C R e t e h a n d l e r) object in the chain is submitted. 6. Collaboration • When the customer submits a request, the request is passed along the chain until there is a ConcreteHandler object to handle it. 7. Effects The Responsibility chain has the following advantages and disadvantages (L i a b i l i t i e s): 1) Reduce the coupling This mode makes an object not to know which object handles its request. Objects only need to know that the request will be processed by "correct". Both the recipient and senders do not have the clear information of the other party, and the objects in the chain do not need to know the structure of the chain. As a result, the responsibility chain can simplify the interconnection of the object. They only need to keep a reference to its rear successor without having to keep all the references to all candidate recipients.
2) Enhance the flexibility of the object assignment duties (R e S P O N S I B I L i T Y) When assigning duties in the object, the duties will give you more flexibility. You can increase or modify those responsibilities that process a request by increasing or modifying the chain to the chain on the running time. You can use this mechanism to use the inheritance mechanism of the static specialty processing object. 3) Do not guarantee that there is no clear recipient that has been accepted, then it will not guarantee that it will be processed - the request may not be processed at the end of the chain. A request may not be processed by the chain is not properly configured. 8. Implementation Here is the implementation problem to be considered in your position: 1) The successor chain can be achieved. a) Define a new link (usually defined in H A N D L E R, but can also be defined by concretehandlers). b) Use existing links. The new link is defined in our example, but you can often use an existing object reference to form a successor chain. For example, in a portion-integral hierarchy, the parent component references can define a successor of one component. Window Components (Wi D g E T) structures may have this link. C O M P O S I T E (4. 3) discusses the parent component reference in more detail. When existing links can support your required chains, you can use them. This way you don't need to define links and save space. But if this structure does not reflect the duties required by the application, you must define additional links. 2) Connecting successors If there is no existing reference to define a chain, you must introduce them yourself. In this case, H A N D L E R not only defines the interface of the request, which is usually also maintained after the later link. Thus, H A N D L E R provides the default implementation of H A N D L E R e q u e s t: h a n d l e r e q u e s T is forwarded to the ensembler (if any). If the CONCRETEHANDLER subclass is not interested in the request, it does not need to redefine forwarding operations because its default implementation is unconditional forwarding. Here is an H e L P h a n d l e R base class, which maintain a successor link: 3) Indicates that the request can have a different method to represent the request. The simplest form, such as in the example of H A N D L E H E L P, the request is a hard-coded operation call. This form is convenient and secure, but you can only forward a fixed set of requests defined by the H a N D L e R class. Another option is to use a process function, which is parameter in a request code (such as a constant constant or a string). This method supports the number of requests. The only requirement is that the sender and the acceptor should agree on how to encode the issue. This method is more flexible, but it needs to distinguish the request code with the conditional statement to dispatch the request. In addition, the request parameters cannot be transmitted with type safety methods, so they must be manually packaged and unpacking. Obviously, it is not safe relative to actions directly. To resolve parameter delivery issues, we can use separate request objects to encapsulate request parameters. R e q u e s T class can clearly describe the request, and the new type of request can be defined by its subclass. These subclasses can define different request parameters. The handler must know the type of request (ie, which RE Q u e s T subclass is used to access these parameters. For the identification request, R e q u e s t can define an accessor (A C C E S S O R) function to return the identifier of the class. Alternatively, if language support is implemented, the recipient can use the type information of the runtime. The following is a framework (S K E T C h), which uses the request object identity request. Types of GET K i N D operation identification requests in base class R e q u e s t: Subclasses can expand the assignment function by redefining H a n d l e q u e s t. Subclasses only processes the requests of interest; other requests are forwarded to the parent class.
This effectively expands (rather than rewriting) H a n d l e r e q u e s T operation. For example, an E x T E N D E D H A N D L E R Sub-class Extended M Y H A N D L E R Version H A N D L E R E Q U E S: 4) Automatic Forward in S M A L T A Lk You can use the D O E S N O T U N D e R St A N D in SmallTalk to forward requests. There is no corresponding method to capture (TRAP IN) by Dosenotunderstand, which can be redefined so that the message can be forwarded to the successor of an object. This does not require manual implementation; classes only handle the requests of interest, but relying on DoesNotunderstand forwarding all other requests. 9. Code Example The following example illustrates how the duties handle requests in a online help system as previously described. Help request is an explicit operation. We will deliver requests between existing parent components in the window component hierarchy to deliver a request in the window assembly in the chain, and we will define a reference in the H a N d L e ie to deliver a reference to the non-window components in the chain. The Helphandler class defines the interface to handle the help request. It maintains a help topic (the default is empty) and keeps a reference to its successor to help process its successor. The key operation is H A N D L E H E L P, which can be redefined by the subclass. Hashelp is an auxiliary operation that checks if there is a related help topic. All window components are subclasses of Wi D g e t abstract classes. Wi D g e t is a subclass of Helphandler because all user interface elements can have relevant help. (We can also use another intensive implementation of mixed classes) in our example, buttons are the first processor on the chain. B u t t o n class is a subclass of Wi D g e T. The Button constructor has two parameters: a reference to the window component that contains its window components and its own help topics. B U t t o n version of the H a n d l e h E L P first tests whether it is its own help topic. If the developer does not define a help topic, use the H A N D L E H E L P in H E L P H A N D L ER to forward the request to its successor. If there is a help topic, then it shows it and the search ends. D i a l o g implements a similar strategy, but its successor is not a window component but an arbitrary help request to process objects. In our application, this successor will be an example of A P P L I C A T I O N. At the end of the chain is an example of A P P L i c a T I O N. This application is not a window assembly, so A P P L i C A T I O N is not a direct subclass of H E L P H A N D L E R. When a help request is passed to this layer, the app provides general information about the application, or it can provide a series of different help topics. The following code creates and connects these objects. The dialogs here involve printing, so these objects are assigned to the printed topics. We can call H A N D L E H E L P to trigger the corresponding help request. To start searching from the button object, just call H A N D L E H E L P: B U T T O N -> H A N D L E H E L P (); in this case, the button will immediately process the request. Note Any HE E L P H A N D L E R can be used as a successor of D i a l o g. In addition, its successor can be dynamically changed. Therefore, no matter where the dialog is used, you can get it correctly related to context. 10. It is known to apply many class libraries to use the duties chain mode to process user events.
For H a N d L e R, they use different names, but the idea is the same: when the user clicks on the mouse or press the keyboard, an event is generated and spread along the chain. Macapp [App89] and ET [WGM 8 8] are called "event handler", S Ymantec TCL library [S YM 9 3 B] is called "b ureaucrat", while N e xt A PP K IT is named "R Esponder". The graphic editor frame U N i D R A W defines the "command" C O m M a N D object, which encapsulates the request to send C O M P O N E N T and C O M P O N E N T Vi E W Object [V L 9 0]. A component or component view can explain a command to perform an operation, where "command" is a request. This corresponds to the method of "object as a request" described in the implementation section. The components and component views can be tissue into a layered structure. A component or component view can explain the command to its parent member, while the parent component can forward it to its parent member, so that the chain is formed. E T Use the duties to process the update of graphics. When a graphic object must update some of its appearance, call I N V A L I D A T E R E C T. A graphic object does not handle I N V A L i D A T E R E C T because it is not enough to understand it. For example, a graphic object can be packaged in some objects such as scroll bar (S C R O L E R S) or amplifier (Z O O M E R s), which transforms its coordinate system. That is to say, the object can be scrolled or enlarged to it is outside the perspective. Therefore, the default I n V A L i D A T E R E C T implements the forward request to the packaged container object. The last object in the forwarding chain is a window (Wi N D O W) instance. When the window receives the request, the failure rectangle is guaranteed correctly. The window notifies the window system interface and requests an update to process I N V A L i D A T E R E C T. 11. Related Mode Responsibilities The Chain is often used with C O M P O S I T E (4. 3). In this case, the parent member of a component can be used as a successor. 5.2 Command - Object Behavior Screen 1. It is intended to package a request to an object, so that you can use different requests to parameterize the customer; for the request queue or record the request log, and support the revocable operation. 2. Alias action (A C T I O N), transaction (TR a N S A C T I O N) 3. Motivation Sometimes the request must be submitted to an object, but does not know any information about the requested operation or requested recipient. For example, the user interface toolbox includes an object such as a button and a menu that performs request response user input. However, the toolbox cannot be explicitly implemented in the button or menu, as only the application of the toolbox know which object is to be done. The designer of the toolbox cannot know the requested recipient or execution. Command mode The toolbox object can request a request to an unspecified application object by turning the request itself into an object. This object can be stored and passed like other objects. The key to this mode is an abstract C O m M a N D class that defines an interface that performs an operation. Its simplest form is an abstract e x e c u T e operation. Specific C O m M A N D subclands use the recipient as an example variable and implements the E x E C U TE operation, specifies the action taken by the recipient. The recipient has the specific information required to perform the request.
With C O m M M a n d, you can easily implement menu (M E N u), and options in each menu are an instance of a menu item (M E N U I T E M) class. A P P L I C A T I O N class creates these menus and their menu items, and the rest of the user interface. The A P P L I C A T I O N-class also tracks the D O C U m e n T object that the user has opened. This application configures an instance of a specific C O m M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M. When the user selects a menu item, the M e n U I TEM object calls its E x E C u t e method of the C O m M a N D object, and E X E C U t e performs the corresponding operation. MEE N u I t e m object does not know which subclass of C O m M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M The C O m M a N don is stored in the requested recipient, and the E x C U TE operation will call one or more operations of the recipient. For example, P A S T E C O m M A N D supports paste the body from the clipboard to a document (D O C U m E N t). The recipient of P A S T E C O M M M A N D is a document object, which is provided by instantiation. The e x e c u t e operation will call the P A S TE operation of the D O C U m E N t. The e x e c u t e operation of O P e n c o m M a N D is different: it prompts the user to enter a document name and create a corresponding
The document object, which entered into the application object of the recipient and opens the document. Sometimes a M e n u i t e m requires a series of commands. For example, the M e N u I t E m M e N u I t E m in normal size can be constructed from a C E N T E R D O C U m E N T C O M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M A ND object. Because this requires a number of commands to be connected in series, we define a M a C R O c O m M a N D class to make one M e n u I t e m perform any number of commands. M a C R O C O M M A N D is a specific C O m M A N D subclass, which performs a command sequence. M a C R O C O m M A N D does not have a clear recipient, and the command in the sequence each defines its recipient. Note that the C O m M a N D mode is the object that decoups the invoke operation and the object having the information required to perform the operation. This makes us have a lot of flexibility in designing the user interface. An application If you want a menu to represent the same function with a button, you can simply share the same instance of the corresponding specific C O m M A N D subclass. We can also dynamically replace C O m M a N D object, which can be used to implement menus related to context. We can also support command scripting by forming a few commands into a larger command. All of this is possible because it is because it is submitted to a request, just know how to submit it without knowing how the request will be executed. 4. Applicability When you have the following requirements may be used C o m m a n d Mode: M e n • as discussed above u I t e m above objects, abstract operation to be performed in a parameterized object. This parameterization mechanism can be expressed in the process language in the process language (C A L B A C K) function. The so-called callback function means that the function is registered at some place, and it will be called at a later need. The C O m m a n d is an object-oriented alternative to a callback mechanism. • Specify, arrange, and execute requests at different times. A C O m M M m M M a N d may have a survival that is independent of the initial request. If a requested recipient can be expressed in a manner that is independent of address space, you can transfer the command object responsible for the request to another process and implement the request there. • Support cancel operation. The e x C U t e operation of C O m M a N D can store status before implementing operations, which is used to eliminate the impact of the operation when the operation is canceled. The C O m M a N D interface must add an U N e x e c u t e operation, which cancels the effect of the last e x e c u t e called. The execution command is stored in a historical list. "Cancel" and "redance" and "re-do" can be achieved by calling the back and forward traversing of this list and call U n e x e c u t e and e x e c u t e. • Support for modifying logs so that these modifications can be redisled once when the system crashes. Add load operations and storage operations in the C O m M A N D interface, which can be used to maintain a consistent modification log. The process recovered from the crash includes re-executing the recorded commands in the disk and re-executing them with the E x E C U t. • Construct a system with a high-level operation that constructs an primitive operation. Such a structure is common in the information system that supports the transaction (T R a N S A C T I O N). A transaction packages a set of changes to the data. The C O m M a N d pattern provides a method of modeling a transaction. C O m m a n D has a public interface that allows you to call all transactions in the same way. It is also easy to add new transactions to expand the system. 5. Structure 6. Participants • C O m M A N D- Declare the interface of the execution operation.
• C O N C R E T E C O M M M M M A N D (p A S T E C O M M A N D) - Binds a recipient object to an action. - Call the recipient's corresponding operation to implement the E x E C U t. • C L i e n t (a pp L i c t i o n) - Create a specific command object and set its recipient. • Invoker (M M E N U I T E M) - Requires this command to perform this request. • R E C E × R (D O C U m E N T, A P L I C A T I O N) - knows how to implement an operation related to execution of a request. Any class may be used as a recipient. 7. Collaboration • C L i E N t Create a C O N C R E TET E C O M M M A N D object and specify its R e c e i v e r object. • A I n V O K E R object stores the C O N C R E TET E C O M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M m M m M m M m M m M m M m M m M m M m M m M m M m M m M m M M
• The I N V O K E R submits a request by calling the E x E C U t e operation of the C O m M a N D object. If the command is revolated, C O N C R e T E C O M M A N D stores the current state before executing the E x C u t e operation is used to cancel the command. • ConcreteCommand object Some of the operations calling it RE C E I V ER to perform the request. The figure below shows the interaction between these objects. It illustrates how C O M M A N D is decoupled with the caller and recipient (and the request therefor). 8. Effects C O m M A N D The following effects: 1) The Command mode will decouple the object of the call operation with the object that knows how to implement the operation. 2) Command is the object of the head and the like. They can be manipulated and expanded like other objects. 3) You can assemble multiple commands into a composite command. It is, for example, the M a C R O c O m M M a N D D described above. Generally speaking, the compound command is an example of the C O m P O S i TE mode. 4) Adding new C O m M A N D is easy because this does not need to change the existing class. 9. The following issues must be considered when implementing C O m M M a N D mode: 1) A command object should reach the ability to achieve the ability of the intelligent level command object. One extreme is that it only determines one recipient and the action of executing the request. The other extreme is that it implements all functions, and there is no additional recipient object at all. When you need to define a command that is unrelated to the existing classes, the latter ultimate mode can be used when there is no suitable recipient, or when a command implicitly knows its recipient. For example, creating a command object of another application window itself may have the same capabilities as any other object. The case where the two extremes is that the command object has sufficient information to dynamically find their recipients. 2) Support cancel (U N D O) and redo (R E D O) If the C O m M A N D provides method reversal (R E V E R S e), the cancel and reform function can be supported by the execution of the operation (eg, U N e x e c u t e or U N D O operation). To achieve this purpose, C O N C R e T E C O M M A N D may need to store additional status information. This status includes: • Receiver object, which actually performs each operation of the request. • The parameters of the operation on the recipient. • If the process of processing the request changes some of the values in the recipient object, these values must also be stored. The recipient must also provide some operations to enable the command to restore the recipient to its previous state. If the application only supports a cancel operation, simply store the last command. To support multi-level cancellation and redo, there is a historical list that has been executed, which determines the number of cancellation and reforms. The historical table stores the command sequence that has been executed. Down traverse the table column and reverse execution (R E V E R S E - E X E C U T I n g) The command is the result of canceling their results; the command is traversed and executed is re-executed. Sometimes you may have to copy a revocable command before it can be placed in the historical list. This is because the command object that performs the original request will perform other requests later. If the status of the command changes between the calls, the copy must be copied to distinguish the different calls of the same command. For example, a delete command to delete selected objects (D E L E T E C O M M A N D) must store different object collections when it is executed each time it is executed. Therefore, the delete command object must be copied after execution, and the copy is placed in the historical table column. If the status of the command is not changed when executed, no copy is required, and only a reference to the command is required in the historical table column. Those C O m M a N d that must be copied prior to placing in historical table is placed (see P R O T O T Y P E-mode (3. 4)).
3) Avoid canceling the error accumulation in the process of implementing a reliable, keeping the original semantic cancellation / redo mechanism, may encounter a lag impact problem. Due to the execution of the command, the process of canceling, and re-executing may accumulate errors, and the status of an application finally deviate from the initial value. This is necessary to store more information in C O m M A N D to ensure that these objects can be accurately restored to their initial state. Here, the ME E M M M M A N D can be used to access this information without exposing internal information of other objects. 4) Use the C template pair (1) Can't be canceled (2) Commands that do not require parameters, we can use the C template to achieve, avoiding each action and recipient to create a C OMMAND class. We will explain this approach at the Code Sample section. 10. Code examples The C code shown here is given the approximate framework of the implementation of the C O m M A N D in the Motivation section. We will define o p E N C O m a N D, P A c R o c o m M a N D. The first is an abstract C O m M M a n-class: o P e n c O m M a n d Open a name specified by the user. Note that the constructor of O P e n C O m M a N D requires a A P P L I C A T I O N object as a parameter. A S K u s e r is a implementation routine that prompts the user to enter the document name to be opened. P A S T E C O M M M A N D requires a D O C U m e n T object as its recipient. The recipient will be used as a constructor of P A S T E C O m M a N D. For a command that cannot cancel and does not require parameters, you can use a class template to parameterize the recipient of the command. We will define a template subclass simpleCommand for these commands. Use the R Eceiver type to parameterize S IMPLE C OMMAND, and maintain a recipient object and the binding between actions, and this action is pointed to a member function. Store. The constructor stores the actions in the corresponding instance variable. E X E C U TEE Operates this action of the recipient. In order to create a C O m M m M M M m M M M M M M M M M M M M M M M M M M M M M M M M, which calls the M Y C L A S class, only the following code: Remember, this scheme is only available for simple commands. More complex commands not only maintain their recipients, but also register parameters, sometimes save the status for cancel operation. At this point, a subclass of C O m M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M a C R O c O m M A N D Manage a sub-command sequence that provides an operation of adding and deleting subcommands. There is no need to explicitly, because these subcommands have defined their respective recipients. The key to M a C R o c o m m a n d is its E x e c u t e member function. It traverses all subcommands and calls its respective E x E C U t. Note that if the M a C R O c O m M A N D implements the cancel operation, its subcommand must perform the cancel operation of each subcommand in order relative to the implementation of E X E C U TE. Finally, Macrocommand must provide the operation of managing its subcommand. M a C R O c O m M M A N D is also responsible for deleting its subcommand. 11. Examples of known applications may have the earliest command mode appear in a paper in L i E B E R M A N [L i E 8 5]. M a C A P P [A P 8 9] This statement is generally accepted by commands that realize the undo operation. E T [W G M 8 8], I N T E R VI E W S [L C i 9 2], and U N i D R A W [V L 9 0] also defines a class that conforms to C O m M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M.
I N t e R VI E W S defines a A c T I O N abstraction class that provides command functionality. It also defines a A c k template, which can automatically generate a C O m M M a N D subclass with a C T I O n method as a parameter. TH I n k class library [S Y M 9 3 B] also supports the revocable operation using the C O m M a N D mode. Commands in T H i n k are called "tasks" (TA S K s). The task object is passed along a CHAIN of Responsiblity (5. 1) for consumption (C O N S U m P I O N). U N i d r a w The command object is very special, and its behavior is like a message. A U N i D R A W command can be given to another object to explain, and the result of the explanation varies depending on the received object. In addition, the recipient can entrust another object to interpret, typically, delegate to a larger structure (such as in a responsible chain) the parent member. Thus, the recipient of the U N i D R A W command is calculated rather than pre-stored. U N i D R A W interpretation mechanism depends on the type information at runtime. C O P L I E N describes how C in C implements F u N C T O R s in C [C O P 9 2]. F u n c t O R is an object that is actually a function. He used the overload function to call the operator (Operator ()) reached a certain degree of transparency. Command mode is different, which focuses on maintenance of the binding between the recipient and function (ie, the action), not only to maintain a function. 12. Related Mode C O M P O S i TE E Mode (4. 3) can be used to implement macro commands. ME E m e n T o mode (5. 6) can be used to maintain a state, command to use this state to cancel it. The command that must be copied before being placed in the historical table to a prototype (3. 4). 5.3 Interpreter (Interpregnum) - Class behavior mode 1. It is intended to give a language, define a representation of its textual law, and define an interpreter that uses this representation to explain the sentence in the language. 2. Motivation If a specific type of problem occurs high enough, it is possible to represent the various instances of this problem as sentences in a simple language. This can be constructed to construct an interpreter that solves this problem by explaining these sentences. For example, searching for a string matching a pattern is a common problem. Regular expressions are a standard language describing string mode. Instead of constructing a particular algorithm for each model, it is better to use a common search algorithm to explain the execution of a regular expression, which defines a collection of strings to be configured. The interpreter mode describes how to define a text method for a simple language, how to represent a sentence in this language, and how to explain these sentences. In the above example, this design pattern describes how to define a text method for regular expressions, how to represent a specific regular expression, and how to explain this regular expression. Considering the defined regular expression: Symbol e x P R e s S i o n is the start symbol, and Litral is the end of the definition of the simple word. The interpreter mode uses classes to represent each textual rule. The symbols on the right side of the rules are the instance variables of these classes. The above grammar uses five classes: an abstract class R egular e xpression and its four subclass l Itel e xpression, a LTERNATIO ne XPRESSION, S EQUENCE E Xpression, and R EPETITION EPETITION EPETITION EPETITION EPRESSION three class defined variable representatives express formula. Each regular expression defined by this literary method is represented as an abstract syntax tree composed of these instances.
For example, abstract syntax tree: regular expression: Raining & (DOGS | CATS) * If we define interpretation for each subclass of R egular e xpression, then it is obtained for these regular expressions. An interpreter. The interpreter uses the context of the expression as a parameter. The context contains information about the input string and how much it has been matched. To match the next part of the input string, the subclasses of each R e G U L A R e x P R e S I O N implement an interpretation operation (I N T E R P R E T) on the basis of the current context. For example, • LiteralExpression will check if the input is matched to the word it defines (L i t e R a L). • AlternationExpression will check whether you match any of its selection items. • RepetitionExpression will check if the input contains multiple expressions it repeats. and many more. 3. Applicability When there is a language that needs to be explained, and you can use the sentence in the language as an abstract syntax tree, you can use the interpreter mode. This mode effect is best when there is the case: • This grammat is simple for complex grammar, and the class level of literacy has become huge and cannot be managed. Tools such as Syntax Analyzer Builders are better options. They can explain their expressions without building abstract syntax trees, which saves space and may save time. • The efficiency is not a key problem. The most efficient interpreter is usually not implemented by direct interpretation of the syntax analysis tree, but first converts them into another form. For example, regular expressions are typically converted into a state machine. But even in this case, the converter can still be implemented by the interpreter mode, which is still useful. 4. Structure (see page map) 5. Participants • A b S T R a C TExEx P R E S I O N (abstract expression, such as R E G U L A R E X P R E S I O N) - A abstract explanation operation, this interface is shared by all nodes in the abstract syntax tree. • TE R m i n a l e x P R E S I O N (Fault expression, such as L i t e R a L e x P R E S I O N) - Implementation operations associated with the end of the characterization. - Each end of a sentence requires an instance of this class. • N o N t e R m I n a L e x P R e s S I O N (non-ender expression, such as AlternationExpression, Repetition-Expression, SequenceExpressions) - Each rule R:: = R:: = R1R2 in the grammat is required.. RN requires an N O N t e R m I n a l e x P R e S I O n. - Example variables of the type A b S t R a c t e x P R e S T R A C TE E X P R E S T R A C TETET are maintained for each symbol from R1 to RN. - Explanation (i N T E R P R E T) operation is performed for non-ending in the text. The interpretation (I N t e R P R e t) is generally recursively invoking the explanation of those objects representing R1 to RN. • C O N t e x t (context) - some global information outside of the interpreter. • C L i E N t (Customer) - Build (or given) an abstract syntax tree in a language defined by this method. The abstract syntax tree is assembled from an example of N o N o N t e R m I N a L e x P R E S I O N and TE R M i N A L E X P R E S I O N. - Call interpretation operation. 6. Collaboration • C L i e n T builds (or given) a sentence, which is an abstract syntax tree of an example of N O N t e R m I n a L e x P R e s I O N and TE R m I n a L e x P R E S I O N. The context is then initialized and interpreted.
• Each non-terminal expression node defines an explanation operation of a corresponding sub-expression. The explanation operation of each end-end expression constitutes a recursive basis. • Interpretation of each node context to store and access the interpreter. 7. Effective interpreter mode The following advantages and deficiencies: 1) Easy to change and expand the grammatism because the mode uses classes to represent the rules of the literacy rules, you can use inheritance to change or expand the grammar. Existing expressions can be changed by incrementally, and new expressions can be defined as variants of old expressions. 2) It is also easy to implement the implementation of the classes of each node in the abstract syntax tree. These classes are easy to write directly, usually they can also be automatically generated with a compiler or syntax analysis program generator. 3) Complex grammar is difficult to maintain the interpreter mode for each rule in the text, at least one class (more classifications that use B NF defined literacy rules). Therefore, it may be difficult to manage and maintain in various rules. Other design patterns can be applied to alleviate this issue. However, when the literary law is very complicated, other technologies such as grammar analysis programs or compiler builders are more appropriate. 4) Increased new interpretation expressive mode makes it easy to implement new expressions "calculations". For example, you can define a new action on the expression class to support the type check of a beautiful print or expression. If you often create a new explanation expression, you can consider using the VI S i T O R (5. 11) mode to avoid modifying the classes of these representative literacy. 8. Implement I N T E R P R E T E R and C O M P O S I T E (4. 3) mode has many communication in realization. Here is some special issues to consider by I N t e r p r e t e r: 1) Creating an abstract syntax tree interpreter mode does not explain how to create an abstract syntax tree. In other words, it does not involve grammar analysis. Abstract syntax trees can be generated with a table-driven grammatical analysis program, or you can use handwritten (usually a recursive drop method) syntax analysis program, or is supplied directly from C L i e n t. 2) Defining the interpretation operation does not have to be explained in the expression class. If you often create a new interpreter, use the VI S i T O R (5. 11) mode to interpret a separate "Accessor" object better. For example, a programming language has many operations on abstract syntax trees, such as type check, optimization, code generation, and more. The appropriate approach is to use an visitor to avoid defining these actions on each class. 3) Interesting the end of the F L Y W E I G H T Mode In some grammar, one sentence may have the same terminator multiple times. It is best to share a single copy of that symbol. A computer program is a good example - each program variable will have multiple times in the entire code. In an example in the motivation section, the terminal DOG (described by L i t E R A L e x P R E S I O N) can also occur multiple times. The termination node usually does not store information about their location in the abstract syntax tree. During the interpretation process, any context information they need is passed by the parent node to them. Therefore, in the shared (internal) state and the incoming (external) state distinguishes clear, this uses F L Y W E I G H T (4. 6) mode. For example, each instance of Dog LiteraleXpression receives a context containing currently matched substring information. And each such L i t eR a l e x P R e s I O N does the same thing in its explanation operation (it checks if the next portion of the input contains a D o G) whether the example appears in the grammar tree. 9. Code Example The following is two examples. The first is a complete example in S M A L t a Lk, which is used to check if a sequence matches a regular expression. The second is a C program for the value of the Boolery expression. Regular expression matches Check if a string belongs to a regular expression definition. Regular expressions are defined by the following text: This method of modifying the example in the motivation section. Because the symbol "*" cannot be used as a suffix operator in S M A L t a lk. Therefore, we replace it with R e p e a t.
For example, regular expression: (('Dog' | 'CAT') Repeat & 'Weather' matches the input string "DOG DOG CAT WEATHER". To implement this match, we define five classes described in the (5. 3) page. Class S Equency E XPRESSION contains instance variables Expression 1 and Expression 2 as a sub-node in an abstract syntax tree; a LTernation e xpression uses instance variables ALTERCATIVE 1 and ALTERCATIVE 2 to store its selection branch; while R Epetition E Xpression is Its instance variable repetition saves its repeated expression. L i t e R A L e x P R E S I O N has a C O m P O N e n t S instance variable, which saves a series of objects (possibly some characters). These representings must match the literal string of the input sequence. M a T C h: Action implements an interpreter of the regular expression. Every class defines the abstract syntax tree has achieved this. It uses I n p u t a t a as a parameter, indicating the current state of the matching process, that is, the partial input of the character string. This state is composed of an input stream, indicating that the regular expression is currently available (currently identified input stream, which is substantially equivalent to all states that may be in the limited number of auto motives). The current state is most important to RE P e a T operation. For example, if the regular expression: 'a' repeat the interpreter can match the "a", "a a", "a a a", and the like. If it is' A 'Repeat &' BC ', you can match "ABC", "AABC", "AAABC", and so on. But if the regular expression is' a' repeat & 'ABC', the sub-expression "' A 'REPEAT "Match Enter" AABC "will generate two input streams, one matching a character, and the other matches two characters. Only that the stream to accept a character matches the remaining "A B C". Now we consider the definition of M A T C H: Define the corresponding regular expression for each class. S e q u e n c e x P R e s S I O n Matches each of its sequences. Usually it will delete the input stream from its I n p U t. One A L T E R N A T I O N e x P R E S I O N returns a state, which is composed of two segments of the selection. A LTERNATION E XPRESSION Match definition is the MATCH of R Epetition E Xpression: Operation finds as many matching status: Its output is usually more state than its input, because R Epetition E XPression can match the input The repeating body is once, twice or more. The output status is to indicate all of these possibilities to allow subsequent regular expressions to determine which state is correct. Finally, LiteraleXpression's M A T C H: Matches each of the possible input streams. It only retains those enabled input streams: where N e x T AV A I L A B L E: Message advances input stream (ie, reading text). This is the only M a T c H: operation that advances input stream. Note that the returned state contains a copy of the input stream, which ensures that matching a L i t E R A L does not change the input stream. This is important because the selection of each A L T E R n a t I o n e x P R e s S I O N should be the same input stream.
Now we have defined various classes that make up an abstract syntax tree, which explains how to build a syntax tree. We can't write a syntax analysis program for regular expressions, but as long as some operations are defined on the R egular e xPression class, you can "calculate" a S MALLTALK expression, resulting in an abstraction corresponding to the regular expression Grammar tree. This allows us to use the S M A L t a lk built-in compiler as a syntax analysis program for a regular expression. To build an abstract syntax tree, we need to define "|", "r e p e a t", and "&" as the operation on R E G U L A R e x P R E S I O N. These operations are defined in the RE G U L A R e x P R E S I O n class: A S R e x P operation will convert L i t E R A L s into R E g U L A R e x P R e s S I O n. These operations define in class S TRING: If we define these operations in the higher level of the class level (SMALLTALK, I NDED C OLECIOTN in SMALLTALK / V), like a ray and o rdered c ollection like this. The class also has the definition of these operations, which makes the regular expression can match any type of object sequence. The second example is to operate and evaluate the Boolean expression in C . In this language, the terminator is a Boolean variable, that is, constant T r u E and F A L s E. Non-ending represents a Boolean expression containing operators and OR and N O T. The literal definition is as follows: For simplicity, we ignore the priority of the operator and assume that the object constructs the syntax tree is responsible for processing this matter. Here we define two operations on Boolean expressions. The first operation is a value value (E V A L u a t e), ie, in one context, of course, the context must be assigned to each variable to a "true" or "false" Boolean. The second operation is a replace, that is, an expression is replaced with a variable to generate a new Boolean expression. Alternative operation Description The decapitator mode can not only be used to find a value of expression, but also as other uses. In this example, it is used to operate the expression itself. Here we only give the details of BooleaneXP, VA R I A B L E e x P and A N D e x P class. Class O r e x p and N o T e x P are similar to A n d e x p. C O n S t a n T specifies Boolean constant. B O O L e a n e xp defines an interface for all classes defined a Boolean expression: class C O N t e x T defines a mapping from the variable to the Boolean value, which we can use to represent the constant T r u e and F a L s E in C . C O N t e x T has the following interface: a VA R i a b L e e x P represents a famous variable: the name of the constructor as a parameter: a value of a variable, returns its value in the current context. Copy a variable to return a new VA R i a b L e x P: 1 6 8 Design mode: can be used for object-oriented software
When replacing a variable with an expression, we check that the variable to be replaced is the variable represented by this object: A N D e x P represents the expression from two Boolean expressions and operations. A N d e x P value is the logic "and" of its operands. A ND E XP C OPY and R EPLACE Operation Cutgerate C OPY and R EPLACE Operations Cutting Its Operations: Now we can define Boolean expressions and seek this expression for X and Y for a given true or false assignment. Form value: This assignment to X and Y, which is determined to be True. The value of this expression is required to change only the value of the context object only on other assignments. Finally, we can replace variable y with a new expression, and re-evaluate: This example shows a very important feature of the interpreter mode: you can "explain" one sentence with multiple operations. In the three operations defined for B O O L e a n e x P, Evaluate is most advancing our ideas that should be doing about an interpreter - that is, it explains a program or expression and returns a simple result. However, the replacement operation can also be considered an interpreter. The context of this interpreter is the name of the replaced variable and replacing its expression, and its result is a new expression. Even copies can also be considered an interconnected interpretation. It may be a bit blamed for replacement and copy as an interpreter because they are just basic operations on the tree. Examples of VI S i T O R (5. 11) illustrate that these three operations can be reorganized into a stand-alone "interpreter" access, thereby displaying deep similarity between them. The interpreter mode is not only the operations distributed in a class hierarchy using C O m P i TE E (4. 3) mode. We think that E V A L u a t e is an interpreter because we believe that the B O O L e a n e x P class level represents a language. For a class hierarchy for indicating the assembly of the car parts, even if it is also used, we are still unlikely to treat the operations such as WE I G H T and C O P Y as an interpreter because we will not treat the car components as a language. This is an angular problem of seeing problems; if we really have the grammar of "Auto Parts Language", it may be considered that the operation on those components can explain the language in some way. 10. The known application interpreter mode is widely used in the compiler for object-oriented language, such as S m a l t a l k compiler. S P E C TA L K Use this mode to explain the description of the input file format [S Z A 9 2]. Q O C A Constraint - Solving Tool Use it to calculate constraints [H h M v 9 2]. Under the broadest concept (ie, distributed in a single operation at the class hierarchy based on C O m P O S I T E (4. 3) mode), almost every system that uses the composite mode also uses the interpreter mode. But generally only when a language is defined in a class level, it emphasizes the use of interpreter mode. 11. Related Mode C O M P O S I TE mode (4. 3): Abstract syntax tree is an instance of a composite mode. F L Y W E G H T Mode (4. 6): Describes how to share the endon in an abstract syntax tree. I TE R A T O R (5. 4): The interpreter can use an iterator to traverse the structure. VI S i T O R (5. 11): Available in maintaining the behavior of each node in an abstract syntax tree in a class. 5.4 Iterator - Object Behavior Model 1. It is intended to provide a method sequential access to each element in a polymeric object, and does not need to expose internal representation of the object. 2. The alias cursor (C u R s O r). 3. Motivation A aggregate object, such as a list, should provide a way to allow others to access its elements, but do not need to expose its internal structure. In addition, for different needs, it may be different ways Traverse this list. But even if you can foresee those traversal operations you need, you may not want the list of various traversal operations.
Sometimes you may need to perform multiple traversal at the same table. Iterator mode can help you solve all these problems. The key idea of this mode is to separate access and traversal of the list from the list object and put it in an iterator (I T E R A T O R) object. The iterator class defines an interface to access the list element. The iterator object is responsible for tracking the current element; that is, it knows which elements have traversed. For example, a list (L i s T) class may require a list iterator (L i S t i t e r a t o r), and the relationship between them is as follows: Before instantiation list, the list must be traversed. Once there is an example of the list iterator, you can sequentially access the individual elements of the list. C URRENT I TEM Operation Returns the current element in the table column, the first element initializes the iterator, so that the current element points to the first element of the list, the NEXT operation advances the current element pointer forward, pointing the next element, and I s D ONE checks if the last element has been crossed, that is, completed this traversal. Separation of traversal mechanisms and list objects allows us to define different iterators to implement different traversal policies without having to enumerate them in the list interface. For example, the filtering form islays (F I L TE E R I N G L I S T I t e R A T O R) may only access elements that meet specific filter constraints. Note that iterators and lists are coupled together, and customer objects must know that a list is a list rather than other aggregate structures. It is best to have a way to change the aggregation class without changing the customer code. This goal can be achieved by promoting the concept of iterators to polymorphic iteration. For example, suppose we have a special implementation of a list, such as S K i P L I S [P U g 9 0]. S K I P L I S is a random data structure having a material similar to a balanced tree. We want our code to apply to L i s T and S K I P L I S T. First, define an abstract list class A B S T R A C T L I S T, which provides a common interface of an operation list. Similarly, we also need an abstract iterator class I T E R A T O R that defines a common iterative interface. Then we can implement specific I T E R A T O R subclasses for each different list. Such an iterative mechanism has nothing to do with the specific polymerization. The remaining problem is how to create an iterator. Since these codes do not rely on specific list subclasses, you cannot simply instantiate a specific class, and let the list object are responsible for creating the corresponding iterator. This requires a list object to provide operations such as C R E A TEE TET ER A T O R, and the client requests call the operation to obtain an iterator object. Creating an iterator is an example of a Factory Method mode (3. 3). We use it here to make a customer can request a suitable iterator to a list object. Factory Method mode generates two class hierarchies, one is a list, one is an iterator. CREATETETETETETETERATOR "Contact" These two class hierarchies. 4. Applicable iterator mode can be used: • Access the content of a aggregate object without exposing its internal representation. • Supports multiple traversal of the aggregate object. • Provide a unified interface to traverse different aggregates (ie, support polymorphic iterations). 5. Structure 6. Participants • I T E R A T O R (iterator) - iterator defines an interface to access and traverse elements. • C O N C R E TET E I T E R A T O R (Specific Iterator) - The specific iterator implements iterator interface. - Track the current position over the aggregation. • A g g r e g A t e (polymerization) - aggregation definition creates the interface of the corresponding iterator object.
• C O N C R E TET E A G G R E G A T E (Specific Aggregation) - The specific aggregation implementation creates an interface of the corresponding iterator, which returns an appropriate example of C O N C R e TE E I TE R A T O R. 7. Collaboration • ConcreteTeiterator traces the current object in the aggregate and can calculate the successive object to be traveled. 8. Effects Iteractor mode There are three important roles: 1) It supports traverses in a variety of ways to traverse a polymeric complex aggregation in different ways. For example, code generation and semantic check are to be traversed to analyze trees. The code generation can be traversed in order or in the fore oriented. Iterator mode makes it easy to change the overhead algorithm: only use an instance of a different iterator to replace the original instance. You can also define subclasses of iterators to support new traversal. 2) Itterator simplifies the aggregated interface with the traversal interface of the iterator, and the aggregate itself no longer needs a similar traversal interface. This simplifies the aggregated interface. 3) You can have multiple traversal status of each iterator on the same aggregation. So you can conduct multiple traverses at the same time. 9. Realize the iterator has many changes and options in achieving. Here are some more important implementations. Implementing an iterator mode often requires trade-offs according to the control structure provided by the language used. Some languages (for example, CLU [LG86]) even support this mode. 1) Who controls the iteration a basic problem is what parties determine the iteration, it is an iterator or a customer who uses the iterator. When it is controlled by the customer, the iterator is referred to as an external itrator, and when it is an iterator, the iterator is referred to as an internal iterator. Customers using external iterators must actively promote the pace of traversal, explicitly request the next element to the iterator. Conversely, if an internal iterator is used, the customer only needs to submit an operation to be performed, and the iterator will perform this operation to each element in the aggregate. The external iterator is more flexible than the internal iterator. For example, if two collections are equal, this feature is easily implemented with an external iterator, and it is almost unable to be implemented in an internal iterator. In the language that does not provide anonymous functions, closes, or like S M a L t a l k and CLOS, the weakness of the internal iterator is more pronounced in languages such as C . On the other hand, the use of internal iterators is relatively easy because they have defined iterative logic. 2) Who defines the over-calendar algorithm iterator is not the only place where the algorithm can be defined. The aggregate itself can also define a transition algorithm and use iterators to store the current iteration in the traversal process. We call this iterator as a cursor because it is only used to indicate the current location. The customer will call the aggregated N e x T operation with this cursor, and the N e x T operation will change the status of this indicator. If the iterator is responsible for traversing the algorithm, it will easily use different iterative algorithms on the same aggregate, and it is also easy to reuse the same algorithm on different aggregations. On the other hand, the passenger algorithm may need to access the polymeric private variable. If so, the over-the-algorithm is placed in the iterator to destroy the polymerization package. 3) How to change this aggregation while changing a polymerization can be dangerous. If the external and internal iterators are respectively referred to in BO O O C h, the external and internal iterators are active (P a C T I v e) iterator [B O 9 4]. The two words "active" and "passive" describe the role of the customer, not the anteratory active or not. The indicator is a simple example of the M e m e n t o mode and there are many and its same implementation issues. The polymerization element increases or deletes the polymerization element when the polymerization can result in two ways to access the same element or miss an element. A simple solution is to copy the aggregation and perform traverses for the copy, but it is generally too high. A robust iterator (Robust Iterator) guarantees that insertion and deletion do not interfere with traversing, and do not copy the aggregation. There are many ways to achieve a robust iterator. Most of these needs to register this iterator to this aggregation. When an element is inserted or deleted, the aggregate either adjusts the internal state of the iterator, or the additional information is maintained inside to ensure the correct traversal.
K o f L E R has made a full discussion on how to achieve a robust iterator in E T [K O F 9 3]. M u r r a y discussion how to achieve a robust iterator for the USL StandardComponents list class [M u R 9 3]. 4) The minimum interface of the additional iterator operation iterator consists of F I R St, N e x T, I S D O N E and C U R E N T I T E M operation. Some other operations may also be useful. For example, the ordered aggregation can be operated by one P R E V I O U S to position the iterator to the previous element. The S K i P TO operation is used in aggregates that have been sorted and indexed, which positions the iterator onto the element object that meets the specified condition. 5) Use polymorphic iterators in C use polymorphic anterators. They require an allocation of the assigulator object with a F A C T O R YM E T H O D. Therefore, they are only used when necessary. Otherwise, the specific iterator is allocated in the stack. The polymorphic iterator has another disadvantage: the customer must be responsible for deleting them. This is easy to cause errors because you easily forget to release an iterator object that uses a heap assignment, especially when an operation is available. And if there is an abnormality triggered, iterator object will never be released. P R O x Y (4. 4) mode provides a remedy. We can use a stack allocated P R O X Y as an intermediate agent of the actual iterator. The agent deletes the iterator in its destructure. Thus when the agent life cycle ends, the actual iterator will be released with it. Even when an abnormality occurs, the proxy mechanism ensures correctly cleared iterator objects. This is an application of the famous C "resource allocation, initialization" technology [e s 9 0]. The following code example gives an example. 6) Itecher can have privileged access iterators to be seen as an extension of its aggregation. Iterator and aggregate are closely coupled. In C , we can let the iterator use a close relationship as a friend (F R I E N d) of its aggregation. This way you don't need to define some operations used only for the iterator in the aggregate class. However, such privileged access may make the definition of new traversal, because it will request to change the aggregated interface to increase another friend. To avoid this, iterator classes can contain some of the important non-public visible members of the PR O T E C TEED operation to access the aggregation class. Iterator subclasses (and only iterative subclasses) can use these P R O T E C T E D to obtain privileged access to the aggregation. 7) The iterator used for the composite object is in the recursive aggregation structure in the C OMPOSITE (4. 3) mode, the external iterator may be difficult to implement because the different objects in this structure are in a plurality of different levels of nested polymerization. Therefore, an external iterator must store a path that the current C OMPOSITE will be stored for tracking the current object. Sometimes it is easier to use an internal iterator. It only needs to be recursively called yourself, which is implicitly stored in the call stack without explicitly maintain the current object location. If the node in the composite has an interface to move from a node to its brother node, the parent node and child nodes, then the cursor-based iterator is a better choice. The cursor only tracks the current node; it can rely on this node interface to traverse the n ext, I s d one, and c urrent i TEM into one operation, which advances to the next object and returns this object If the traverses end, then this operation returns a specific value (for example, 0) flag of the iteration. This way we make this interface smaller. The composite object. Composition often needs to be traversed in a variety of methods. Pre-sequence, sequenis, order, and breadth priority are common. You can use different iterator classes to support different traversal. 8) Airlars an email (N u L i t e R A T O R) is a degraded iterator that helps to process boundary conditions. Depending on the definition, a N u L i t e R A T O R has always completed traversal: that is, its I S D O N e operation always returns T R u e.
The email makes it easier to traverse the aggregation of the tree structure (such as a composite object). Each node during the traversal process can request an iterator that traverses each sub-node point to the current element. The aggregation element will return a specific iterator. However, the leaf node element returns an example of N u L i t e R A T O R. This allows us to use a unified manner throughout the structure. 10. Code Sample We will take a look at the implementation of a simple L I S class, which is part of our base library (Appendix C). We will give the implementation of the two iterator, and one traversed the list in the order of the previous arrival, and the other is traversed in the order beforewards (the base library only supports the first one). Then we explain how to use these iterators, and how to avoid defining a particular implementation. After that, we will change the original design to ensure that the iterator is removed correctly. The last example example exemplifies an internal iterator and compares its corresponding external iterator. 1) The list and iterator interface first let us see the part L i s T interface related to the iterator. For a complete interface, please refer to Appendix C. The L i S T is a reasonable and effective way to support iterations through its public interface to support iterations. It is enough to achieve these two traversal. Therefore, there is no need to give the iterator's access privilege of the underlying data structure, that is, the iterator class is not a list of friends. To ensure transparent use of different traverses, we define an abstract iterator class that defines the iterator interface. 2) Realization list of iterative units The iterator is a subclass of an iterator. The implementation of L i S t i t e R a t O r is simple and straightforward. It stores the index of the L i s t and the list of current locations. C U R RE N. F i r s t plas an iterator in the first element: n e x t advances the current element forward: I S DO N e checks whether the index of the current element exceeds the list: Finally, the currentItem returns the element of the current index pointing. If it is askly it is termination, throw an I TERATO RO UT O F B OUNDS Exception: r EveSe L IST I Teerator is almost the same, but its F IRST operation will _ current placed at the end of the list, and N ext operation will be _ Current minus one, further in the direction of the header. 3) Use iterators to assume that there is an employee (E M P L O Y E E) object's List, and we want to print the information of all employees contained in the list. E M P L O Y E E Category The information of the itself is printed with a P R I n t. To print this list, we define a P RINT E MPLOYEE action, this action is parameter with an iterator, and uses the iterator traversal and prints this list: I have implemented two traverses from the back and from the previous two traverses Iterator, we can use this operation to print employee information in two order: 4) Avoid defining a specific list implementation considering a variant Skiplist that is L IST will affect iterative code. The S K I P L I s T subclass of L i s T must provide a corresponding iterator S K i P L I S T I t e R a T O R that implements the I t e R A T O R interface. Internally, in order to perform efficient iteration, S K I P L I S T I T E R A T O R must maintain a plurality of indexes. Since S K I P L I S T I T E R A T O R enables I T E R A T O R, P R I N T E M P L O Y E E O operation can also be used to store list of employees stored with S K i P L I S. Although this method is feasible, it is preferable that it is best not to specify specific L i s T, which is S K i P L I S). To this end, an A B S T R A C T L I S class can be introduced to a different list. L i S T and S K I P L I S are subclasses of A B S T R A C T L I S T.
To support polymorphically iteration, A B S T R A C T L I S T defines a Factory method called C R E A TE E I T E R A T O R. Each list sub-class heavy defines this method to return the corresponding iterator. Another way is to define a general M i X I n class TraveSable, which defines a use of an iterator interface. The polymerization is supported by mixing (inherited) TR A V E R S A B L e to support polymorphism. L i s T Refine C R E A TET E I T E R A T O R, Returns a L i S T I T E R A T O R Object: Now we can write code that does not depend on print employee information indicated by a specific list. 5) Make sure the iterator is deleted Note that C R e a t e c r e a t e i t e R A T O R returns a dynamically allocated iterator object. After use, you must delete this iterator, otherwise the memory leak will be caused. To facilitate customers, we provide an i t e R A T O R P T R as an iterator's agent, which ensures that it clears it when the I TE E R A T O R is separated from the scope. I TE E R A T O R P T is always allocated on the stack. C automatically calls its destructor, and the destructor will delete the true iterator. I TE E R A T O R P R Heavy carries the operators "->" and "*" so that I T E R A T O R P T is used as a pointer to the iterator. All members of I T E R A T O R P T R are inline so they do not produce any additional overhead. You only need to define the private N e W and D E L E T E operator to ensure this at compile time. No additional implementation is required. I TE E R A T O R P T R Simplifies Print Code: 6) An internal Listiterator is finally let us see how an internal or passive L i S t i t e R A T O R class is implemented. At this time, the iterator is controlled, and the same operation is performed on each element in the list. The problem is how to implement an abstract iterator that supports different operations of each element of the list. Some languages support so-called anonymous functions or closures, using these mechanisms to facilitate abstract iterators. But C does not support these mechanisms. At this point, there are at least two ways to choose from: (1) deliver a function pointer (globally or static) to the iterator. (2) Depending on the subclass generation. In the first case, the iterator passes each step in the iterative process to its operation, in the second case, the iterator calls the operation of the subclass weight to achieve a specific behavior. These two options are not perfect. It is often necessary to accumulate (a C C U m U L A T E) status during iteration, while the function is used to achieve this function is not suitable; because we will have to use static variables to remember this state. I TET ER A T O R Subs provide us with a convenient place to store accumulated states, such as in an instance variable. But create a subclass for every different traversal need to do more work. Below is a general framework for implementing a method, which utilizes subclasses. Here we call the internal iterator as a L i S T TR a V E R S E R. L i s T TR a V E R S E R is parameter in an example of one L i S T. Inside, it uses an external L i S t i t e R A T O R to traverse. TR a V e R s E starts traverse and operates the P R O c e s I t e m for each element. The internal iterator can terminate this traversation in advance when the PR O c e s S i t E m operation returns F a L s E. TR A V e R s e returns a boolean value indicating whether the traversal is terminated in advance. Let's use a L i S T TR a V E R S E R to print the header 1 0 employees in the list of employees.
To achieve this purpose, a subclass of L i S T TR a V e R s E R must be defined and redefine its P R O C E S I T E M operation. We count the printed employees in a _ C O U N T instance variable. Below is the PR i N t n e m p L o y e e ie How to print the first 1 0 employees in the list: Note that the customer does not need to explain how to perform iterative loops. The entire iterative logic can be reused. This is the main advantage of the internal iterator. But it is more complex than external iterators because a new class must be defined. Compare with external iterators: The internal iterator can encapsulate different types of iterations. For example, the Iterate of the FilteringListtr Averser encapsulates only those list elements that can be tested: This class interface adds the same TE St I TEM outside the test, which is the same as the L IST TR AVERSER, and its subclass will redefine TE ST I TEM is specified for the required test. TR A V e r s e determines whether or not the current element continues to traverse according to the results of the test: This class is to make TR A V E R s E return value indicate whether at least one element is passed through test. 11. It is known to apply an iterator in the object-oriented system. Most set libraries provide an iterator in different forms. Here is an example of a popular set library -b OOCH component [B OO 9 4], which provides two implementations of a queue: fixed-size (boundless) implementation and dynamic growth Implementation. The interface of the queue is defined by an abstract q u e u e class. To support different queue implementation polymorphism, the queue antector is implemented based on an abstract Q u e u E-class interface. The advantage of doing this is that there is no need for each queue to implement a Factory Method to provide the appropriate iterator. However, it requires an abstract Q u e u e-class interface to power enough to effectively achieve universal iterators. It is not necessary to explicitly define iterators in S M a L L t a lk. Standard set class (package, collection, dictionary, ordered set, string, etc.) define an internal iterator method D o: It is parameter as a block (ie closure). Each element in the collection first is bound to a local variable in blocks, then the block is executed. S M A L L K also includes some S T R E A M-class that supports an interface similar to an iterator. R e a d s t R E a M is essentially an iterator, and it can be used as an external iterator for all sequential sequences. There is no standard external iterator for non-sequential set classes such as collections and dictionaries. TR a V e R s e operation in these examples is a Template method with primitive operation of TE S t I t e m and P R O c e s I t e m. (5. 1 0) E T container [W G M 8] provides the polymorphic iterator discussed earlier and the P R O X Y responsible for clearing iterators. U N i D R A W graphics editing framework uses an indicator-based iterator [V L 9 0]. O B J E C T Wi N D O W 2. 0 [B O R 9 4] provides an iterator class hierarchy for the container. You can use the same method for different container types. O B J E C T Wi N D O W Iterative Syntax Revenue Corpoal Promotion Iteration. 12. Related Mode C O M P O S I T E (4. 3): Itecher is often applied to a recursive structure such as a composite. Factory Method (3.3): The polymorphic iterator replaces the appropriate iterator subclass by Factory Method. M E M e n t o (5. 6): It is often used with iterator mode. The iterator can use one M e m e n t o to capture an iteration. The iterator stores M e m e n t o. 5.5 Mediator - Object Behavior Model 1. It is intended to encapsulate a series of object interactions with a mediation object. The intermediaries make the objects need not be explicitly cited to each other, making them rolling, and can independently change the interaction between them.
2. Motivation object-oriented design encourages the behavior into each object. This distribution may cause many connections between the objects. In the worst case, every object knows all other objects. Although multiple objects can be reused into many objects, it is usually enhanced, but the surge between inter-object interconnection will reduce its reuse. A large number of interconnections make one object seems unlikely to work without other objects - the system appears as an inextricable whole. Moreover, any greater changes to the behavior of the system are very difficult because behavior is distributed in many objects. As a result, you may have to define a lot of subclasses to customize the behavior of the system. For example, consider the implementation of a dialog box in a graphical user interface. The dialog box uses a window to show a series of window components, such as buttons, menus, and input domains, etc., as shown below. There is a dependency between the window components in the usual dialog. For example, when a specific input domain is empty, a button cannot be used; selecting an expression in a column option called a list box may change the content of an input domain; in turn, enter the text in the input domain Select one or more of the list boxes in one or more list boxes; once the body appears in the input domain, other buttons may become able to use, these buttons allow users to do some operations, such as changing or deleting these body Finger. Different dialogs will have different dependencies between different window components. Therefore, even if the dialog box displays the same type of window components, you cannot directly reuse the existing window components classes; they must be customized to reflect the dependencies of the specific dialog. Due to many classes involving many classes, they will be able to customize them with a way to generate subclasses one by one. This problem can be avoided by encapsulating collective behavior in a separate intermediar (M E D i a T O R) object. The intermediaries are responsible for controlling and coordinating interactions between groups. The intermediaries act as a mediation to make the objects in the group no longer explicitly referred to each other. These objects only know the intermediaries, thereby reducing the number of interconnects. For example, F O N T D i a L O G D i R E C T O r can be used as a intermediaries between windows in a dialog. F O N T D i a L O g D i R E C T O r Knows each window component in the dialog, and coordinates the interaction between them. It acts as a transfer center between communication between the window components, as shown below. The following interaction illustrates how each object works together to process changes in the list box. The following series of events make the selection of a list box to a input domain: 1) The list box tells its operator it has changed. 2) The leader gets the selected selection from the list box. 3) The leader passes the selection to the entrance domain. 4) Now the entrance domain has a body, the leader makes it to initiate an action (such as "half black body", "skewers") of a (some) buttons available. Note how the leader is intermediary between dialogs and entry domains. Communication between windows assemblies is indirectly made by the leader. They don't know each other; they only need to know the leader. Moreover, because all of these behaviors are partially in a class, they can change and replace these behaviors as long as they extends or replace this class. What is shown here is how F o N T D i a L O G D i R e c t o r abstraction is integrated into a class library, as shown below. D i a l o g D i R e c t O r is an abstract class that defines the overall behavior of a dialog. Customer calls S H o W D i a l O g Operation Displays the dialog box on the screen. C R e a t e Wi D g e t s is an abstract operation of the window component that creates a dialog. Wi D g e t c h a n g e d is another abstract operation; window components call it to inform it that they have changed. Subcombs for D i a l O g D I R E C T O R will redefine C R e a t e Wi D g e t s to create a correct window assembly and redefine Wi D g e t c h a n g e d to handle its change. 3. Applicability Use the intermediard mode in the following cases: • A set of objects communicate in a well-defined but complex manner. The resulting interdependent relationship structure is confusing and difficult to understand. • An object refers to many other objects and communicates directly with these objects, causing difficult to multiplexing the object. • Want to customize a behavior distributed in multiple classes, and do not want to generate too much subclasses. 4. Structure A typical object structure may be shown in the following page.
5. Participants • M E D i a T O R (intermediaries, such as D i a L O g D i R E C T O R) - The intermediaries define an interface to communicate with each colleague (C O L E A g u e) object. • C O N C R e t E M e D i a t o R (specific intermediaries, such as F O N T D i a L O g D i R E C T O R) - The specific intermediaries achieve collaborative behavior by coordinating each colleague object. - Understand and maintain all colleagues. • Colleague Class (Colleagues, such as ListBox, Entryfield) - Every colleague class knows its intermediaries object. - Each colleague object communicates with its intermediaries when they need to communicate with other colleagues. 6. Collaboration • Colleagues send and receive requests from a media object. The intermediaries forward requests in their colleagues to achieve collaborative behavior. 7. Effects Intermediate Mode has the following advantages and disadvantages: 1) Reduce the subclass of ME E D i a T O R set together the behavior between multiple objects. Changing these behaviors only need to generate subclasses of M E D i T A T O R. Such various C O L E A g u e categories can be reused. 2) It decouples each C O L1 G u e decoupled M E D i a t O r. You can independently change and reuse each C O L E A G u E Class and M E D i a T O R class. 3) It simplifies a pair of interactions between the object protocol with M e D i a t o r and each C O L1 G u E instead of multiple interactions. A pair of relationships are more readily understood, maintained and expanded. 4) It works on how to collaborate abstall the intermediary as an independent concept and package it in an object, so that you will focus on the behavior of your own own itself to the interaction between them. This helps figure out how objects in a system interact. 5) It makes the control centralized intermediar pattern turn the complexity of the interaction into intermediaries. Because the intermediaries encapsulate the agreement, it may become complicated than any C O L1 E A G u e. This may make the intermediaries themselves become a huge thing that is difficult to maintain. 8. Implementation below is some implementation issues related to the intermediard mode: 1) Ignoring the abstract ME E D i a T O R Class When each C O L E A G u e works with one M e D i a t o R, there is no need to define an abstract M E D i a t O R class. Abstract coupling provided by M e D i a t O R has enabled each C O L E A G u e to work with different M e D i a t O R subclasses, and vice versa. 2) C O L1 G u e-m e D i a t O R Communication When an incident of interest occurs, Colleague must communicate with its M e D i a t O R. One implementation method is to use O b S e R (5. 7) mode to implement M E D i a t O r as an O b S E R V E R, each C O LE E A G U E As S UB J E C T, once its state changes transmit notification to M e D i a t O r. The response made by M e D i a t O r is to propagate the results of the state change to other C O L E A g u e. Another method is to define a special notification interface in M E D i a t O r, each C O L1 G u e calls the interface directly during communication. The S M a L L T a L K / V under Wi N D O W S uses some form of proxy mechanism: When communicating with M e D i a t O R, Colleague passes itself as a parameter to M E D i a T O R, so that it can identify the sender. This method is used in the code example section. The implementation of S M A L t a l k / v will be discussed in the known application section later. 9. Code Example We will use a D i a L O G D i R E C T O R to implement the font dialog shown in the Motivation section.
Abstract class D i a l o g d I r e c t O r defines an interface for the leader. Wi D g e t is an abstract base class of a window assembly. A window component knows its leader. CH A N g e d invoking the leader 's Wi D g e t c h a n g e d. Notifying the leader an important event happens. Subcarpse of D i a l O g D I R E C T O R Refines Wi D G E T C H A N G E D to lead the corresponding window assembly. The window assembly uses a parameter for its own reference as the parameters of Wi D g e t c h a n g e d, so that the leader can identify which window component changes. D i a L O g D I R E C T O R Subwise Reduction Purity Function C R E A TE E WI D G E TH, build a window component in the dialog. L i s t b O x, E n T R Y F I E L D and B U T T O N are subclasses of Wi D g e t, which are used as a particular user interface constituting element. L i s t b O x provides a G E T S E L E C T I O N operation to obtain the current selection, and the S e T TE X T operation of E N T R Y F I E L D will put a new body into the domain. B u t t o n is a simple window component that calls C H a N g e d once it is pressed. This is completed in the implementation of H A N D L E M O U S E: F O N T D i a L O G D I R E C T A T O R Class in the window assembly in the dialog box. F O N T D i a L O G D I R E C T A T O R is a subclass of D i a L O G D I R E C T O R: F O N T D i a L O G D i R E C T O R Tracks the window assembly it displayed. It redefines C R e a t e Wi D g e t s to create a window component and initialize a reference to them: Wi D g e t c h a n g e d ensuring that the window assembly works correctly: the complexity of Wi D g e t c h a n g e d increases with the increase in complexity of the dialog box. In practice, the big dialog box is not popular, the reason is multifaceted, one of the important causes is that the complexity of the intermediar may offset the benefits of this mode in other ways. 10. It is known to apply E T [W G M 8 8] and Think Class Class Class Class [S Y M 9 3 B] Both the dialog box to use the target of the target as the intermediaries between the window assembly. The application structure of S m a l t a l k / v under Wi N d o W s is based on intermediard structure [L A L 9 4]. In this environment, an application consists of a window containing a set of panes (P A n e). This class library contains several predefined P A N e objects; such as TE X T P a N E, L I S T B O x, Button, and the like. These panes can be used directly without inheritance. Application developers only need to be derived from VI E W M a g e R derivatives, VI E W m a n a g e ● Responsible for coordination between panes. VI E W M A N A G E R is a american, and each pane only knows its View Manager, it is seen as the "master" of the pane. The pane is not directly referenced. The following object map shows a scenario for an application running time. One event mechanism is used in P a g e-vi e w m a n a g e-vi e w m a n a g e-vi e w m a n a g e-vi e w m a n. When a pane wants to get information from the intermediaries or when it wants to notify some important things that happen, it produces an event. The event defines a symbol (such as # S E L E C T) to identify the event. To process the event, the manager registers a candidate method for the pane. This method is the handler of the event; once the event occurs, it will be called.
The following code segment illustrates in a VI EW m anager subclass, a L IST P ANE object How to create and VI EW m Anager How to register an event handler for # select event: Another intermediarian mode is used Coordinating complex updates. An example is CH A N g E m a n a g e R class mentioned in O b S E R (5.7). C H a N g e m a n a g e r coordinated between S UB J E C T and O B S E R V E R to avoid redundant updates. When an object changes, it notifies C H a N g e m a n a g e r, and ChangeManager will notify those objects depending on the object to coordinate this update. A similar application appears in U N i D R A W Drawing Frame [V L 9 0], which uses a class called C S O L V E R to implement connection constraints between "connectors". Objects in the graphic editor can be expressed in different ways. Connectors For automatic maintenance of applications, such as block diagram editing and circuit design systems. C S O L V E R is a mediator between the connector. It explains the connection to constraints and updates the position of the connector to reflect these constraints. 11. Related Mode F A C A D E (4. 5) The difference from the intermediaries is that it is an abstraction of a subject subsystem, providing a more convenient interface. Its protocol is one-way, that is, the F A C A D e object makes a request for this subsystem class, but it will not. In contrast, M e D i a t O r provides collaborative behavior that each C O L E A G u e object does not support or cannot support, and the protocol is multi-directional. C O L1 E A G u E can communicate with M e D i a t O R using O b S e R (5.7) mode.