Deeply decorating

xiaoxiao2021-03-06  45

First, the primer

Decorative mode? Definitely let you think of a black and fire home decoration. In fact, both in the truth still have a lot of similar places. Family decoration is nothing more than to cover up the wall of the original, unfair, and put a layer of inexperous paint, let life a little color. The wall is still the wall, his essence has not changed, but it is only a layer of coat.

What is the decorative pattern in the design pattern?

Second, definition and structure

Decorative mode is also called wrapper. GOF is defined in the "Design Mode" book as: dynamically adds additional duties to an object. In terms of increased function, Decorator mode is more flexible compared to generated subclasses.

Let us understand this sentence. Let's design the "door" class. Suppose you as the "door" class as follows:

Now, in one place in the system, you need a DOOR that can alarm, how do you do it? You may write a Sub-class ALARMDoor, add a sub-class unique method ALARM (). Well, where you use alarms you must let customers know that the alarm is used, otherwise this unique approach cannot be used. Moreover, this also violates the LISKOV replacement principles.

Maybe you have to say, then add this method to DOR, this is not unified? But all doors must have alarm, at least a "dumb" alert. And when your system uses a warning in one or two places, this is obviously unreasonable - although the default adapter can be used to make up.

At this time, you can consider adding additional features to your door dynamics.

Let's take a look at the composition of decorative model, don't worry about solving the above problems, I will understand it under the following!

1) Abstract component role (Component): Defines an abstract interface to standardize an object to receive additional responsibility.

2) Concrete Component: This is a decorator that defines a class that will be decorated to increase the function.

3) Decorative role (Decorator): Holding an example of a component object and defines an interface of an abstract component definition.

4) Concrete Decorator: Responsible for adding a added function to the component.

Look at the categories of decorative patterns:

In the figure, ConcreteComponent may inherit other systems, and he also implements the Component interface in order to achieve decorative mode. The structure of the entire decorative mode is implemented in combination mode, but the purpose of attention is completely different (regarding the differences on the two, please pay attention to my future article).

Third, for example

This example is still from the JUnit that I have recently studied. If you still don't understand JUnit, you can refer to "JUnit Getting Started", "JUnit Source Code Analysis (1)", "JUnit Source Code Analysis (2)", "JUnit Source Code Analysis ( three)". It is worthy of Erich Gamma, one of GOF, and small things use n types of patterns in it. Let's take a look at the decorative mode in JUnit.

In JUnit, TestCase is a very important class that allows for functional extensions.

In the JUnit.extensions package, TestDecorator, RepeatedTest is an extension of TestCase's decorative mode. Below we put them and the role on the top of the top.

Oh, look at the source code, this is the most direct!

// This is an abstract component role

Public interface test {

/ **

* Couns the number of test case tria 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);

}

// Content object object, but here is an abstract class

Public Abstract Class Testcase EXTENDS Assert Implements Test {

......

Public int counttestcases () {

Return 1;

}

......

Public TestResult Run () {

TestResult result = cretesult ();

Run (result);

Return Result;

}

Public void Run (TestResult Result) {

Result.run (this);

}

......

}

// Decorative role

Public Class TestDecorator Extends Assert IMPLEments TEST {

// Here, a case of a component object is retained in accordance with the above requirements.

Protected test ftest;

Public TestDecorator (Test Test) {

ftest = TEST;

}

/ **

* The Basic Run Behaviour.

* /

Public void Basicrun (TestResult Result) {

ftest.run (result);

}

Public int counttestcases () {

Return ftest.counttestcases ();

}

Public void Run (TestResult Result) {

Basicrun (Result);

}

Public string toString () {

Return ftest.toString ();

}

Public test gettest () {

Return ftest;

}

}

// The specific decorative role, this type of enhancement is to set the number of test classes.

Public class repeatedTest Extends TestDecorator {

Private int fTimeSrepeat;

Public REPEATEDTEST (TEST TEST, INT REPEAT) {

Super (test);

IF (Repeat <0)

Throw New IllegalargumentException ("Repetition Count Must Be> 0");

FTimeSremeSrepeat = Repeat;

}

// Take a look at how to decorate

Public int counttestcases () {

Return super.counttestcases () * fTimeSrepeat;

}

Public void Run (TestResult Result) {

For (int i = 0; i

if (Result.ShouseStop ())

Break;

Super.run (result);

}

}

Public string toString () {

Return super.toTOString () "(repeated)";

}

}

When using it, you can use the following manner:

TestDecorator test = new repeatedTest (New Testxxx (), 3); Let us recall the "door" of the above mentioned above, this alarm door uses the decorative mode, which can be generated in the following manner.

Doordecorator alarmdoor = new alarmdoor (new door ());

Fourth, application environment

The following uses are given in the GOF book:

1) Add responsibility to a single object in a dynamic, transparent manner without affecting other objects.

2) Handling responsibilities that can withdraw.

3) When the method of generating subclasses cannot be expanded. One case is that there may be a large number of independent extensions, to support each combination, which will generate a large number of subclasses, resulting in explosive growth. Another situation may be because class definitions are hidden, or class definitions cannot be used to generate a subclass.

What is the case where JUnit is used to analyze. First, a more flexible manner than static inherits is achieved, and the dynamic increase function is achieved. Imagine all implementations of TEST to increase a function by inheritance, meaning that there are a lot of functions similar to subclasses, which is obviously not appropriate.

Moreover, this avoids the high-level classes having too much feature, such as abstract categories with alerts mentioned above.

Five, transparent and translucent

For interface programming, you should try to make the customer programs don't know the specific type, but should operate with an interface. This requires decorative roles and specific decorative roles to meet the LISKOV replacement principles. Like this:

Component C = New ConcreteComponent ();

Component C1 = New ConcreteDecorator (C);

This application is called transparent in JUnit. In practical applications, such as Java.IO often requires public new methods (this is also for reuse) because of too much extension to the original interface. So it is often impossible to conceal the specific type on the client program. This method is called "translucent".

In java.io, it is not an example of pure decorative mode, which is a decorative mode, a mix of adapter mode.

Sixth, other

System design using Decorator mode tends to generate many small objects that look similar, these objects are only different in their way, rather than their classes or their attribute values. Although those who understand those systems are easy to customize, it is difficult to learn these systems, and it is also difficult to troubleshoot. This is the shortcomings of the decorative model mentioned by GOF. Can you experience it? What they said, I think it means the specific decorative role. This is the side effects of an object dynamically added function.

Seven, summary

I finally finished, I didn't know if I didn't say it. Please correct!

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

New Post(0)