In-depth combination mode

xiaoxiao2021-03-06  48

First, the primer

In the university's data structure, the tree is one of the most important chapters. Remember how the tree is defined? Tree (Tree) is a limited set of n (n ≥ 0) nodes, t is an empty tree, otherwise it meets the following two conditions:

(1) There is only one specific node called root (root);

(2) The remaining nodes can be divided into M (M ≥ 0) subsets TL, T2, ..., Tm, T2, ..., TM, each of which is a tree, called it as a root tree. Subtree.

The recursive definition given above portrays the intrinsic characteristics of the tree: a non-empty tree is made of several subtroductions, while the subtree can be composed of several smaller subtots. The subtree here can be a leaf or a branch.

The combination mode to learn today is to have a tree structure and a recursive relationship.

Second, definition and structure

The other translation name of the Composite mode is also a lot, such as synthesis mode, tree mode, etc. The definitions given in the "Design Mode" are: organize the objects in a tree structure to achieve a "part-overall" hierarchy such that the client has consistency for a single object and combined object.

The environment where the combined mode can be obtained from the definition: "Part-Overall" hierarchy that wants to indicate the object in the design; it is desirable that the user ignores the different objects and individual objects, uniformly uses all objects in the combined structure.

See the composition of the combination mode.

1) Abstract component role Component: It declares the interface in a combination, or it can achieve default behavior for a common interface.

2) Leaf member role Leaf: The leaf node object is indicated in the combination - there is no sub-node to realize the interface of the abstract component role statement.

3) Branches Component Role Composite: The branch node object-there is a branch node object - there is a sub-node to implement an interface of the abstract component role declaration; storage sub-components.

The figure below shows the class diagram of the combination mode.

As shown in the figure: A Composite instance can pass it like a simple Leaf instance, you can pass it to any method or object that uses Component, and it is like a Leaf.

It can be seen that the combination mode makes this design structure very flexible, and further confidence is obtained in the example below.

Third, safety and transparency

The management method of the child object must be provided in the combination mode, otherwise it will not complete the addition of the sub-object, and the flexibility and scalability are lost. But the management method is declared in Component or in composite?

One way is to declare all methods for managing subclass objects in Component to maximize the Component interface (as shown below). The purpose is to make customers seem to have no difference - transparency of leaves and branches at the interface level. However, the leaves do not exist, so some methods of Component declare are not applicable to leaves. This also brings some security issues.

Another way is to declare all methods for managing sub-objects (as shown below) in CompositeE. This avoids the safety problem of the previous way, but because the leaves and branches have different interfaces, transparency is lost.

"Design Mode" One book believes that in this mode, we compare transparency relative to security. The method that does not need in the leaves node in the first mode can be solved using an empty process or an abnormality report.

Fourth, an example

Here is the application of the combination mode in JUnit as an example (Getting Started with JUnit).

JUnit is a unit test framework, and the unit test can be automated in accordance with the specification under this framework. To achieve the purpose of "automation", two concepts are defined in JUnit: TestCase and TestSuite. TestCase is a test class written for a class or JSP, and TestSuite is a collection of different TestCase. Of course, this collection can also contain TestSuite elements, which runs all TestSu all runs all of them. However, when you have a test program, you don't need to care about this class is TestCase or TestSuite, we only care about how to test the results. That's why JUnit uses a combination mode.

JUnit creates a Test Interface to play a TestCase and TestSuite in order to adopt a combined mode, and create an abstract component role, so that the original TestCase plays a combination mode role, while the TestSuite plays the branches in the combination mode. The relevant code of these three classes is as follows:

// Test interface - abstract component role

Public interface test {

/ **

* Counts the number of test case tres. Will be run by this test.

* /

Public Abstract Int countTestCases ();

/ **

* Runs A Test and Collects ITS Result In A TestResult Instance.

* /

Public Abstract void Run (TestResult Result);

}

The section of the TestSuite class For the source code - Composite role, it implements the interface TEST

Public Class Testsuite Implements Test {

// With an older vector to save the added test

Private vector ftests = new vector (10);

PRIVATE STRING FNAME;

......

/ **

* Adds a test to the suite.

* /

Public Void AddTest (Test Test) {

// Note The parameters here are Test types. This means that TestCase and TestSuite and any classes that implement the Test interface in the future can be added.

Ftests.addeElement (Test);

}

......

/ **

* Counts the number of test case tres. Will be run by this test.

* /

Public int counttestcases () {

INT count = 0;

E.HASMOREELEMENTS (); {

TEST TEST = (TEST) E.NEXTELEMENT ();

Count = count Test.countTestcases ();

}

Return count;

}

/ **

* Runs The Tests and Collects Their Result In A TestResult.

* /

Public void Run (TestResult Result) {

E.HASMOREELEMENTS (); {

if (Result.ShouseStop ())

Break;

Test test = (test) E.NEXTELEMENT (); // Key in this method

Runtest (Test, Result);

}

} // This method is the recursive call. As for what type of Test is only when it is running, I know the public void runtest (Test Test, TestResult Result) {Test.Run (Result);} ...

}

Some of TestCase For the source code --leaf role, your prepared test class is inherited from it

Public Abstract Class Testcase EXTENDS Assert Implements Test {

......

/ **

* Counts the number of test case executed by run (test result).

* /

Public int counttestcases () {

Return 1;

}

/ **

* Runs the test case and collects the results in testResult.

* /

Public void Run (TestResult Result) {

Result.run (this);

}

......

}

It can be seen that this is a combination mode of a preemptive security. Therefore, when using TestCase and TestSuite, you cannot use Test instead.

Five, advantages and disadvantages

As can be seen from the example above, the combination mode has the following advantages:

1) Make the client calls simple, the client can consistently use the combined structure or a single object, the user does not have to care about whether a single object or the entire combination structure, which simplifies the client code.

2) It is easier to add object components in the combination. The client does not have to change the code because of the new object parts. This is in line with the requirements of the opening and closing principle, which is advantageous for the second development and functional extension of the system!

Of course, the combination mode is less than the disadvantage: the combined mode is not easy to limit the components in the combination.

Six, summary

The combination mode is a very wide design pattern, which is used in the interpreter mode that has been described above, and the combined mode is used in the enjoys. It is simple but very connotation, which has great help to your development design.

Here, I wrote a summary of my learning combination mode, I hope to bring you help, I hope you can give it to correct.

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

New Post(0)