2012-08-22 10 views
12

vedo su decorator example in Python:Decorator in Java

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> 

e ottenuto alcuni curiosi come si può implementare in Java, quindi cercare e avuto qualche esempio di utilizzo 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>"; 
    } 

} 

come faccio a fare questo come l'esempio Python sopra utilizzando un'annotazione Java come questo:

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

Ho avuto qualche problema quando ho cercato di fare il campione, il problema è che non so come posso passare il valore str dal metodo main al BoldWrapper e ItalicWrapper in modo che possa concatenare e come restituire esso, in modo che ilIl metodopuò visualizzare il risultato che è stato concatenato.

prega di avvisare se c'è qualcosa di sbagliato con la mia comprensione di annotazione.

+2

no, non si sta andando ad essere in grado di fare questo con annotazioni. –

+0

C'è un altro modo per farlo con java senza usare Decorator Design Pattern? – Crazenezz

+0

Si può fare la decorazione di oggetti in Java bene, ma non con le annotazioni. –

risposta

1

1) Il link che hai citato è buono: rende giustizia al "Pattern Decoratore" rispetto a Java. "Design Patterns" se stessi, naturalmente, sono indipendenti da qualsiasi particolare linguaggio OO:

2) Ecco un altro buon collegamento:

In Java, un esempio classico del pattern di decoratore è l'implementazione degli stream di I/O Java.

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

4) Quindi sì, il "modello decorator" è un buon candidato per questo problema.

Personalmente, preferirei questo tipo di soluzione:

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

5) Tuttavia le annotazioni sono anche un'opzione. Per esempio:

1

Se siete particolarmente interessati a fare questo genere di cose con annotazioni (non si ha realmente):

Questo esempio dovrebbe iniziare:

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

Anche se questo non risolve come utilizzare le annotazioni come si voleva, invece di usare il "design decoratore", potrei proporre usi il "builder design" se si adatta meglio alle tue esigenze (sembra così).

rapido esempio di utilizzo:

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

uscita: torta {zucchero = 0.75, burro = 0.5, uova = 2, Vanila = 2, la farina = 1,5, lievito chimico = 0.0, latte = 0.5, ciliegio = 0}

per la piena attuazione e una buona spiegazione, si prega di controllare http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html

+0

Grazie mille per le informazioni, l'utilizzo del Pattern Builder è la chiave per risolvere il problema. Ma voglio ancora approfondire se possibile usare Annotation per risolvere il problema. E so anche che l'uso dell'annotazione ha effetti collaterali per la memoria. – Crazenezz

Problemi correlati