Design mode from Java class library

zhaozj2021-02-16  87

UML software engineering organization

Designing design mode from Java class library (Composite, Strategy, Iterator) IBM DW Liu Wudong (WDLiu@chinaren.com) January 2002

In addition to a structural composite mode, this article will have two behavior patterns to debut. In fact, in the previous content, we have come into contact with behavioral mode: Observer and Command are two typical behavior patterns. Behavioral mode focuses on the assignment of algorithms and objects of duties, that is, it focuses on the semantics between the object collaborations such as this mode system, and stream control of communication between the objects. The Composite mode is undoubted, the Component-Container system in the AWT is an example of a good composite mode. Container inherits in Component, and the Container can include multiple Component because the Container is actually Component, so the container can also contain Container. Thus, a tree hierarchy is formed by combining the object of the Component-Container structure. This is also what the Composite mode is done. Composite mode is to simplify programming. Generally, when programming, if strictly distinguished Component and Container, sometimes it will bring a lot of inconvenience, and these often do not need. For example, I want to place a Component in a Container, I don't need to know this component is a Container, or a general component, what to do in the parent container, just record a Component's reference, in need Time to call the COMPONENT to display this component. When this Component is indeed a Container, it can complete the display of this container by the Container reload, complete the display of this container and pass the drawing message to its sub-object. That is to say, for a parent container, it is not concerned about it, and its child object is a Component, or a Container. It needs to treat Component and Container.

Figure 11: The class chart of the Composite mode Composite mode is relatively simple, and it is not complicated, but there is a certain limit. For example, when processing trees, we often need to handle three types of objects: subtails, page nodes, and non-page nodes. The distinction between sub-trees and non-leaf nodes in Composite mode is not obvious, but it is combined into a Composite object. And in the Composite mode of GOF, for the method of adding, deleting sub-nodes belonging to the CompositeTe object, it is placed in the Component object, which although it can distinguish when it is realized, but it is easy to cause some concepts. Misunderstanding. From the above, we can propose a modified Composite mode to introduce sub-tree objects, thereby separating subtrands and non-leaven nodes, as shown below: Figure 12: Composite: Composite Mode Although COMPOSITE The Component class is separated, but does not harm the connotation of the Composite mode. Do not necessarily have the above, there are different applications, but sometimes it is easier to use such a method to handle the child, conceptual. The following code shows a simple model of a Composite Java implementation: public abstract class Component {public abstract void operation (); public void add (Component component) {}; public void remove (Component component) {};} import java .util *;. public class Composite extends Component {String name; ArrayList children = new ArrayList (); public Composite (String name) {this.name = name;} public void add (Component component) {children.add (component) } public void recapone (Component Component);} public void Operation (); {system.out.println (name); item itrator = children.iterator (); while (item.hasnext ()) {Component Child = (Component) Iterator.Next (); child.operation ();}}} public class leaf extends Component {string name; public leaf (string name) {this.name = name;} public void operation () {System.out.println (Name);}} Strategy Mode The Strategy mode is mainly used to separate the algorithm from the class, and package it in a separate class. Simply simple, the objects are decoupled in two parts that are closely linked to their behavior (Behaviour), which are placed in two different classes. This makes it possible to switch different implementation algorithms to the same behavior. Through the package of the strategy, new strategies can be easily introduced for them to provide a unified interface. AWT's LayoutManager is an example of a Strategy mode.

For GUI, the emissions of each component in the container need to follow certain algorithms. The usual method is to use absolute coordinates, just like the tools such as VB, Delphi, record the positions in the container. This of course brings some problems. For example, when the form is scaled, it is necessary to manually encode the size and position of the component to make the original scale to be saved. In AWT, the concept of layout manager is introduced, making the layout method greatly rich, and the encoding process is also simple. A container, such as Applet, Panel, etc., only records the components therebetween, and the layout manager encapsulates an algorithm for layout components in the container. Specifically, it is to specify the size of the components and the size of the components in the container. With the layout manager, you only need to determine the relative position between the components you want to place, this aspect simplifies the encoding, and on the other hand, it also helps the software's platform independence. Figure 13: The relationship between the container and layout manager in the AWT has a layout manager. When the container needs to arrange its components, it calls the layout manager's method to arrange the components in the container. LayoutManager2 inherits in LayoutManager, providing a more detailed layout function, which allows the layout manager to add constraints to the constraints that the components have been arranged. For example, in order to determine where the component is placed in the border, BorderLayout adds a direction indication on its components. Special, the custom layout strategy can be easily implemented by implementing the LayoutManager or LayoutManager2 interface. Back to the topic of the pattern, if there are several very similar classes, the difference is only different in individual behavior, and you can consider using the Strategy mode. In this way, through a strategic combination, the original plurality of classes are streamlined into a class with multiple policies. This is very compliant with the principle of OO design: find some changes, and encapsulate it! The Strategy mode is also a good alternative to subclass inheritance. When using the inheritance mechanism, the change of behavior is static, you can change it once - and the strategy is dynamic, you can switch any time frequency. More importantly, policy objects can be shared by different objects in different environments. Take the layout manager as an example, although each container has only one layout manager, a layout manager can work for multiple containers. Figure 14: STRATEGY mode class diagram Strategy mode There are also some shortcomings, for example, the application must know all policy objects and from the neuturies. And when the policy object is used, it is usually tight between it and the Context object, and the Context object must provide data or other things related to the specific algorithm for the policy object, and the delivery of these data may not be loaded. Abstract land policy class, because all algorithms are needed. Alternatively, because the policy object is usually created by the application, the Context object cannot control the Life period of Strategy, and in the concept, this policy should be subordinate to the Context object, and its life does not exceed the range of contexts. Usually, Strategy is easy to confuse with Bridge mode. Indeed, they have a very similar structure, but they are designed to solve different problems. The Strategy mode focuses on the encapsulation of the algorithm, and Bridge mode focuses on separating abstraction and implementation, providing different implementations for an abstract system.

The Iterator mode Itrator pattern is used to specify traversal interfaces to a certain data structure. The iTerator interface is introduced in the Collection Framework in the Collection Framework to provide traversal of a collection. Each Collection class defines a Iterator () method that is inherited from the Collection interface, to get an Iterator object, we call it a traveler, the Iterator interface is simple: Hasnext (): Used to determine in the travers Is there a next element. Next (): Returns the next element in the traveler. Remove (): Delete the object that is last returned in the Collection class traveled. Take the most common Vector as an example, see how the Iterator mode is implemented in the Collection Framework. Prior to this, we need to understand some of the structure of the Vector and Collection Framework. The Collection Interface is the foundation of this Framework that is inherited or implemented by all other set classes. For the Collection interface, there is a basic implementation to abstract class AbstractCollection, which implements most of which are not related to the specific data structure. For example, if an object is present in the contAins () method exists in this collection class: public boolean contacts (object o) {ipi = = iperator (); if (o == null) {while (E.hasNext ()) IF E.next () == null) Return True;} else {while (E.SASNEXT ()) f (} (E.NEXT ())) Return True;} Return False;} This is called for Iterator () The method is an abstract method that depends on the implementation of the specific data structure. However, for this containers () method, it is not necessary to know the specific Iterator implementation, but only need to know the interface it provides, it is possible to complete a type of task, which is the work of abstract methods in the abstract class. Other non-abstract methods implemented in AbstractCollection, most of them are implemented on the Iterator interface provided by the Abstract Method Iterator () method. This design method is a key to introducing abstract classes, which is worth careful. The List interface inherits the Collection interface, providing abstraction of the list collection class; the corresponding AbstractList class inherits the AbstractCollection and implements the List interface as a abstract base class for the list. It is also the same in the realization of non-abstract methods, and it is also the same as AbstractCollection, which is no longer sentenced. Corresponding to the collection of Iterator, List has its own listiterator, Listiterator inherits to Iterator and adds some methods dedicated to List traversal: Boolean Hasprevious (): It is determined whether there is an element before the current element in the list. Object previous (): Returns the element before the current element in the list. Int nextIndex (): int readyIndex (): Void Set (Object O): Listiterator provides a stronger functional interface for List.

In AbstractList, a specific Iterator () method and listiterator () method are implemented, let's take a look at how these two methods are implemented: public iterator iterator () {return new itr (); // ITR is an internal class } private class iPlements itrator {int CURSOR = 0; // iTerator counter indicates the location INT LastRet = -1 of the element that is returned when the next () method is currently calling the next () method; / / Indicates that it has just passed NEXT () or Previous The position of the element returned, and -1 // means that the remove () method has deleted an element. // MODCOUNT is the field defined in the AbstractList, indicating the number of times the list is modified. Iterator uses // This value checks if the list of its packages is illegally modified by other methods. INT EXPECTEDMODCOUNT = MODCOUNT; Public Boolean Hasnext () {RETURN CURSOR! = size ();} public object next () {Try {// GET method is still an abstract method, depending on the specific subclass implementation object next = GET ( cursor); // check list is being incorrectly modified checkForComodification (); lastRet = cursor ; return next;} catch (IndexOutOfBoundsException e) {checkForComodification (); throw new NoSuchElementException ();}} public void remove () {if (Lastret == -1) throw new illegalStateException (); checkforcomodification (); try {// The same remove (int) also depends on the specific subclass to implement AbstractList.This.Remove (Lastret

转载请注明原文地址:https://www.9cbs.com/read-13783.html

New Post(0)