Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorator in Java

I see about decorator example in Python:

def makebold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

def makeitalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makebold
@makeitalic
def hello():
    return "hello world"

print hello() ## returns <b><i>hello world</i></b>

And got some curious how it can be implement in Java, so I search and got some example using Decorator Design Pattern.

public class Main {

    public static void main(String[] args) {
        Wrapper word = new BoldWrapper(new ItalicWrapper());
        // display <b><i>hello world</i></b>
        System.out.println(word.make("Hello World"));
    }
}

public interface Wrapper {

    public String make(String str);

}

public class BoldWrapper implements Wrapper {

    private Wrapper wrapper;

    public BoldWrapper() {

    }

    public BoldWrapper(Wrapper wrapper) {
        this.wrapper = wrapper;
    }

    @Override
    public String make(String str) {
        if(wrapper != null) {
            str = wrapper.make(str);
        }

        return "<b>" + str + "</b>";
    }

}

public class ItalicWrapper implements Wrapper {

    private Wrapper wrapper;

    public ItalicWrapper() {

    }

    public ItalicWrapper(Wrapper wrapper) {
        this.wrapper = wrapper;
    }

    @Override
    public String make(String str) {
        if(wrapper != null) {
            str = wrapper.make(str);
        }

        return "<i>" + str + "</i>";
    }

}

How do I make this like the Python example above using a Java Annotation like this one:

public class Main {
    public static void main(String[] args) {
        @BoldWrapper
        @ItalicWrapper
        String str = "Hello World";
        // Display <b><i>Hello World</i></b>
    }
}

public @interface BoldWrapper {
    public void wrap() default "<b>" + str + "</b>";
}

public @interface ItalicWrapper {
    public void wrap() default "<i>" + str + "</i>";
}

I got some problem when I tried to make the sample, the problem is I don't know how I can pass the str value from the main method to the BoldWrapper and ItalicWrapper so it can concatenate and how to return it, so the main method can display the result that has been concatenate.

Please advise if there is something wrong with my understanding of annotation.

like image 223
Crazenezz Avatar asked Aug 22 '12 02:08

Crazenezz


People also ask

Where is decorator pattern used in Java?

Decorator design pattern is used to modify the functionality of an object at runtime. At the same time other instances of the same class will not be affected by this, so individual object gets the modified behavior.

What is decorator in OOP?

In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class.

What is decorator pattern used for?

The Decorator Pattern allows class behavior to the decorated dynamically. It's a structural design pattern as it's used to form large object structures across many disparate objects. The concept of decorator is that it adds additional attributes to an object dynamically.

How do decorator patterns work?

Decorator pattern allows a user to add new functionality to an existing object without altering its structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class.


1 Answers

If you are particularly interested in doing this kind of stuff with annotations (you don't have to really):

This example should get you started:

public class AnnotationTest
{
    @Target( ElementType.METHOD )
    @Retention( RetentionPolicy.RUNTIME )
    public static @interface TagWrapper
    {
        public String[] value() default {};
    }

    public static interface TextFragment
    {
        public String getText();
    }

    public static class TagWrapperProcessor
    {
        public static String getWrapperTextFragment( TextFragment fragment )
        {
            try
            {
                Method getText = fragment.getClass().getMethod( "getText" );
                TagWrapper tagWrapper = getText.getAnnotation( TagWrapper.class );
                String formatString = "<%s>%s</%s>";
                String result = ( String ) getText.invoke( fragment );
                for ( String tag : tagWrapper.value() )
                {
                    result = String.format( formatString, tag, result, tag );
                }
                return result;
            }
            catch ( Exception e )
            {
                throw new RuntimeException( e );
            }
        }
    }

    public static class BoldItalicFragment implements TextFragment
    {

        private String _text;

        public BoldItalicFragment( String text )
        {
            _text = text;
        }

        @Override
        @TagWrapper(
        {
            "b", "i"
        } )
        public String getText()
        {
            return _text;
        }

    }

    @Test
    public void testStuff()
    {
        System.out.println( TagWrapperProcessor.getWrapperTextFragment( new BoldItalicFragment( "Hello, World!" ) ) ); // prints: <i><b>Hello, World!</b></i>
    }
}
like image 70
Strelok Avatar answered Oct 07 '22 11:10

Strelok