简体   繁体   中英

How to use Decorator Design in this case?

The following is my test code. The case is: I try to create a view that allows many decorators to be attached on, like scroll bars, extra subviews, backgroundColor, special effect on this view, etc. The problem is I find that i1 and i2 is not what really I need, what I need is whatINeed1 and whatINeed2 . In this case, what is the point of having i1 and i2 . Don't they become like a generator in this case?

The syntax may be wrong in many places because I tested in objective-c but copied and tailored the java sample code online.

If I am wrong from the beginning, could you please point it out!

public class Decorator {

abstract class I implements DefaultView { I render(); }

static class A implements I { public I render() { System.out.print( 'A' ); } }

static abstract class D implements I {
   private I core;
   public D( I inner ) { core = inner; }
   public I render()  { return core.render();  }
}

static class X extends D {
   public X( I inner ) { super( inner ); }
   public I render()  {
      I i = super.render();
      i.setBackgroundColor();
   }
}

static class Y extends D {
   public Y( I inner ) { super( inner ); }
   public I render()  {
      I i = super.render();
      View v = new View();
      //This is objective-c similar syntax,
      //I don't know what's equivalent to Java
      i.addSubview(v);
   }
}

public static void main( String[] args ) {
   I i1 =new X( new A() )
   I i2= new Y( new X( new A() ) )};
   I whatINeed1 = i1.render();
   I whatINeed2 = i2.render;
}

Talking about Decorator design is Adding extra features without modifying the existing code. How do I achieve the model shown below? How to draw border and scrollbars without modifying the source code? scrollbars need to interact with original window. 在此处输入图片说明

Decorator is usually used to add additional "features" to a Class X(methods let's say) WITHOUT modifying the source code of X.

ie

public class PlayerScore{ 
    void setScore(int); 
}

We want to add a method that allows us to get the rank of the score in a ladder but we cannot/don't want to modify PlayerScore.. Then:

public class MyPlayerScore extends PlayerScore{
    PlayerScore component;

    int getRank() { /**some code**/}
    void setScore(int x){ component.setScore(x);}

}

By the looks of your code, you are really not adding functionalities. The base class I already has the functionalities setBackgroundColor(), addSubView() etc, you are just calling them in the subclasses.

This looks like a mixture of inheritance and composition pattern, rather than Decorator, even though the composition part (made by passing the Component to the constructor) makes it look like a Decorator.

Your code is fine if it works for you but if you wanted to use the Decorator pattern, you would add more and more methods to the inheriting classes as you need to obtain more and more specialized behaviour for those classes (class PanelView would add void scroll() for example)

More info on decorator: https://en.wikipedia.org/wiki/Decorator_pattern

EDIT(1):

To use decorator to add a scrollbar to a parent View, a Window let's say, the parent class must expose some form of interface that the new Decorated class can use to implement the scrolling behaviour. For example, If window had a method that returned a handle to the some Graphics API, let's call the handle 'g', then a decorator class ScrollPane could do the following:

public class ScrollPane extends Window{
    Window component;
    void renderScrollBar(){
        Graphics g = window.getGraphicsHandle();
        g.drawRectangle(/** some coords for where to put the bar **/);
        /** some extra code to add logic on the scroll bar,
        /** such as shifting the Window content up or down and cull out
        /** the portion that is outside of the ScrollPane.
        /** For example, openGL could allow you to do this with scissor 
        /** test **/
    }

    void render(){
        component.render();
        this.renderScrollPane();
    }
}

https://www.khronos.org/opengl/wiki/Scissor_Test if you are interested in that last part of the comment.

This is how you could go about it. Obviously implementing a well functioning scroll pane may take some more thinking but in terms of laying out your class architecture, the Decorator pattern would serve you well in designing a GUI.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM