Structural Design Patterns

Source: Internet
Author: User
Tags dashed line

Overview of structural Design Patterns

A structured design pattern is used to handle a combination of classes or objects that describe how classes and objects are organized together to form large structures that enable new functionality.

Mechanism of implementation:

The structured object pattern uses a combination/aggregation mechanism to combine classes, including bridge mode (bridges), combined mode (Composite), adorner mode (Decorator), appearance mode (facade), the enjoy meta-mode (FlyWeight), and proxy mode.

The structural class model employs an inheritance mechanism to combine classes, including adapter mode (Adapter).

(i) appearance (facade) mode (façade mode)

Questions raised:

In software systems, the client program often generates coupling with the internal subsystems of the complex system, causing the client program to change as the subsystem changes. So how do you simplify the interface between client programs and subsystems? How do you decouple the dependencies between the internal subsystems of a complex system and the client program?

(i) appearance (facade) mode

public class Class1 {

public void Method1 () {

....

}

}

public class Class2 {

public void Method2 () {

....

}

}

public class Class3 {

public void Method3 () {

....

}

}

public class Class4 {

public void Method4 () {

....

}

}

If the client program wants to use Class1, Class2, CLASS4 to complete a business function, use CLASS3, Class1 to complete another business function.

public class Clientnofacade {

public void MethodA () {//complete the first business function

Class1 C1 = new Class1 ();

C1.method1 ();

Class2 C2 = new Class2 ();

C2.METHOD2 ();

CLASS4 C4 = new Class4 ();

C4.METHOD4 ();

}

public void MethodB () {//complete the second business function

CLASS3 C3 = New Class3 ();

C3.method3 ();

Class1 C1 = new Class1 ();

C1.method1 (); }

}

(ii) adorner (Decorator) mode

Problem: In software systems, sometimes we use inheritance to extend the functionality of the object, but because of the static characteristics introduced by the type of inheritance, so that the extension of the lack of flexibility, and with the increase in the number of subclasses (expansion of the function), the combination of each seed class (extension function of the combination) will cause more sub-class expansion. How do you enable the "Expansion of object functionality" to be implemented dynamically, as needed? At the same time, avoid the problem of sub-class expansion caused by the increase of expansion function.

Consider the scenario:

Starbucks stores are almost bloom around the world. They offer a variety of delicious coffees: Irish coffee, Blue Mountain Coffee, cappuccino, and Nestle. Each kind of coffee has its own description attribute and charge behavior. They are also available in a variety of ingredients: milk, sugar, ice cubes, soy milk. Different coffees add different ingredients to calculate the price is not the same.

How to design?

It is rubbish to implement it in an inherited way.

Let's change the idea:

Now the user ordered a cup of Irish double milk coffee, and what we're going to do is:

Create an Irish coffee object

Decorate it with milk

and decorate it with milk.

Call the cost () method and rely on the delegate to calculate the price of the ingredient

Code implementation:

Coffee interface

Package com.lovo.decoretor;

Public interface Coffee {

public int cost ();

}

Decorator class

Package com.lovo.decoretor;

Public abstract class Drcoretor implements Coffee {

@Override
Public abstractint cost ();

}

Ingredients

Package com.lovo.decoretor;

public class Bingdecoretor extends Drcoretor {

Private Coffee Coffee;

Public Bingdecoretor (Coffee Coffee) {
This.coffee = coffee;
}


public int cost () {
TODO auto-generated Method Stub
return 2+coffee.cost ();
}

}

Ingredients

Package com.lovo.decoretor;

public class Naidecoretor extends Drcoretor {

Private Coffee Coffee;

Public Naidecoretor (Coffee Coffee) {
This.coffee = coffee;
}
public int cost () {
TODO auto-generated Method Stub
return 1+coffee.cost ();
}

}

Blue Mountain Coffee

Package com.lovo.decoretor;

public class Lanshancoffee implements coffee{

@Override
public int cost () {
TODO auto-generated Method Stub
return 10;
}

}

Test

Package com.lovo.decoretor;

public class Testdecoretor {

public static void Main (string[] args) {

Coffee Coffee = new Lanshancoffee ();

System.out.println (Coffee.cost ());

Coffee = new Naidecoretor (coffee);

Coffee=new bingdecoretor (coffee);

System.out.println (Coffee.cost ());
}

}

The various roles in the adornment mode are:

Abstract component (Component) role: An abstract interface is given to standardize the objects that are ready to receive additional responsibilities.

Concrete Component (concrete Component) Role: Defines a class that will receive additional responsibilities.

Decoration (Decorator) Role: Holds an instance of a component (Component) object and defines an interface that is consistent with the abstract component interface.

Specific decoration (concrete Decorator) role: Responsible for attaching the Component object "affixed" to the responsibility.

(iii) static proxy mode

Problem: In software systems, some objects sometimes because of cross-network or other obstacles, but can not or do not want to directly access another object, if the direct access to the system brings unnecessary complexity, this time can be between the client program and the target object to add a layer of middle tier, Let the proxy object do everything in place of the target object.

For example:

Package com.lovo.proxy;

Public interface Book {

public void Sellbook ();
}

Agent

Package com.lovo.proxy;

public class Bookproxy implements book{

Private Realsubject R;

Public Bookproxy (Realsubject R) {
Super ();
THIS.R = R;
R = new Realsubject ();
}

@Override
public void Sellbook () {
R.sellbook ();
}

}

Package com.lovo.proxy;

public class Realsubject implements book{

@Override
public void Sellbook () {
System.out.println ("sell book");
}

}

Test

Package com.lovo.proxy;

public class Test {

public static void Main (string[] args) {

Book B = new Bookproxy (new Realsubject ());
B.sellbook ();
}
}

(iv) Bridge mode

Questions raised:

In a software system, some types, because of their own logic, have two or more dimensions that change, so how do you deal with this "multidimensional change"? How can you use object-oriented technology to make this type easily change in multiple directions without introducing additional complexity?

For example:

Package com.lovo.Bridge1;

Public interface Draw {

public void Draw ();
}

Package com.lovo.Bridge1;

Public interface Shap {

public void Mydraw ();
}

Package com.lovo.Bridge1;

public class Huanshixian implements draw{

@Override
public void Draw () {
SYSTEM.OUT.PRINTLN ("Drawing solid Line");
}

}

Package com.lovo.Bridge1;

public class Huaxuxian implements draw{

@Override
public void Draw () {
System.out.println ("Draw dashed line");
}

}

Package com.lovo.Bridge1;

public class Juxing implements shap{
private int width;
private int height;
private draw draw;

public juxing (int width, int height, draw draw) {
Super ();
This.width = width;
This.height = height;
This.draw = Draw;
}

public int getwidth () {
return width;
}

public void setwidth (int width) {
This.width = width;
}

public int getheight () {
return height;
}

public void setheight (int height) {
This.height = height;
}

@Override
public void Mydraw () {
System.out.println ("Draw rectangle: Long:" +this.width+ ", High:" +this.height);
Draw.draw ();
}

}

Package com.lovo.Bridge1;

public class Test {

public static void Main (string[] args) {
Draw draw = new Huanshixian ();

Shap s = new juxing (+, draw);

S.mydraw ();
}
}

(v) Adapter (Adaptor) mode (class, adapter mode of the object)

The question is raised:

The interface of a class is transformed into another interface that the client expects, so that two classes that are not able to work together because of an interface cause mismatch can work together.

Suppose we want to pile, there are two kinds: square piles and round piles.

public class squarepeg{

public void Insert (String str) {

System.out.println ("Squarepeg insert ():" +str);

}

}

public class roundpeg{

public void Insertintohole (String msg) {

System.out.println ("Roundpeg insertintohole ():" +msg);

}

}

Now there is an application that requires both a square pile and a round pile. Then we need to combine these two non-relational classes. Suppose Roundpeg we don't have source code, or source code we don't want to modify, then we use adapter to implement this application

public class Pegadapter extends squarepeg{

Private Roundpeg roundpeg;

Public Pegadapter (Roundpeg peg) {

This.roundpeg=peg;

}

public void Insert (String str) {

Roundpeg.insertintohole (str);

}

}

In the above code, Roundpeg belongs to Adaptee, which is the appropriate ligand.

The Pegadapter is adapter, adapting Adaptee (the adapter roundpeg) and Target (Squarepeg).

In fact, this is the combination method (composition) and the Inheritance (inheritance) method is used synthetically.

Pegadapter is inherited squarepeg, if we need to inherit from both sides, that is, inherit Squarepeg and inherit Roundpeg, because Java does not allow multiple inheritance, but we can implement (implements) two interfaces (interface)

public interface iroundpeg{

public void Insertintohole (String msg);

}

public interface isquarepeg{

public void Insert (String str);

}

The new Roundpeg and Squarepeg

public class Squarepeg implements isquarepeg{

public void Insert (String str) {

System.out.println ("Squarepeg insert ():" +str);

}

}

public class Roundpeg implements iroundpeg{

public void Insertintohole (String msg) {

System.out.println ("Roundpeg insertintohole ():" +msg);

}

}

The new Pegadapter

public class Pegadapter implements Iroundpeg, isquarepeg{

Private Roundpeg roundpeg;

Private Squarepeg squarepeg;

Construction method

Public Pegadapter (Roundpeg roundpeg, Squarepeg squarepeg) {

This.roundpeg=roundpeg;

This.squarepeg=squarepeg;

}

}

Structural Design Patterns

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.