Подтвердить что ты не робот

Декоратор в Java

Я вижу о декораторе пример в 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>

И получилось любопытно, как это можно реализовать на Java, поэтому я искал и получил пример с помощью Design Design Design.

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>";
    }

}

Как сделать это как пример Python выше, используя Java-аннотацию, подобную этой:

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>";
}

У меня возникла проблема, когда я попытался сделать образец, проблема в том, что я не знаю , как я могу передать значение str из метода main в BoldWrapper и ItalicWrapper поэтому он может конкатенировать и , как вернуть его, поэтому метод main может отображать результат, который был конкатенатным.

Пожалуйста, сообщите, если что-то не так с моим пониманием аннотации.

4b9b3361

Ответ 1

1) Ссылка, которую вы указали, является хорошей - она ​​справедливо относится к "шаблону декоратора" относительно Java. Разумеется, "шаблоны проектирования" не зависят от какого-либо конкретного языка OO:

2) Вот еще одна хорошая ссылка:

В Java классическим примером шаблона декоратора является реализация потоков ввода-вывода Java.

FileReader       frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);

4) Итак, да, "шаблон декоратора" является хорошим кандидатом для этой проблемы.

Лично я бы предпочел такое решение:

   String myHtml = 
     new BoldText (
       new ItalicText (
         new HtmlText ("See spot run")));

5) Однако аннотации также являются опцией. Например:

Ответ 2

Если вы особенно заинтересованы в том, чтобы делать подобные вещи с аннотациями (вам это не обязательно):

В этом примере вам нужно начать:

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>
    }
}

Ответ 3

Хотя это не позволяет решить, как использовать аннотации, как вы хотели, вместо использования "дизайна декоратора", я мог бы предложить вам использовать "конструктор-конструктор", если он лучше подходит вашим потребностям (кажется, что так).

Пример быстрого использования:

public class BuilderPatternExample {

    public static void main(String args[]) {

        //Creating object using Builder pattern in java
        Cake whiteCake = new Cake.Builder()
                                 .sugar(1)
                                 .butter(0.5)
                                 .eggs(2)
                                 .vanilla(2)
                                 .flour(1.5)
                                 .bakingPowder(0.75)
                                 .milk(0.5)
                                 .build();

        //Cake is ready to eat :)
        System.out.println(whiteCake);
    }
}

Вывод: Торт {сахар = 0,75, масло = 0,5, яйца = 2, ванила = 2, мука = 1,5, разрыхлитель = 0,0, молоко = 0,5, вишня = 0}

Для полной реализации и очень хорошего объяснения, пожалуйста, проверьте http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html