2012-08-22 11 views
12

veo sobre decorador example en Python:decorador en 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> 

y de algunos curiosos cómo se puede implementar en Java, por lo que la búsqueda y tiene algo de ejemplo usando 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>"; 
    } 

} 

¿Cómo puedo hacer esto como el ejemplo de Python anterior utilizando una anotación de Java como éste:

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

Tengo un poco de problema cuando traté de hacer la muestra, el problema es que no sé cómo puedo pasar el valor str del método main a la BoldWrapper y ItalicWrapper por lo que puede concatenar y cómo devolver, así que elEl métodopuede mostrar el resultado que ha sido concatenado.

Aconsejo si hay algo de malo en mi comprensión de la anotación.

+2

no, no vas a ser capaz de hacer esto con anotaciones. –

+0

¿Hay alguna otra manera de hacerlo con Java sin utilizar el patrón de diseño del decorador? – Crazenezz

+0

Puede hacer la decoración de objetos en Java muy bien, pero no con anotaciones. –

Respuesta

1

1) El enlace que ha citado es bueno, hace justicia al "Patrón de decorador" con respecto a Java. "Design Patterns" sí, por supuesto, son independientes de cualquier lenguaje orientado a objetos en particular:

2) Aquí hay otro buen enlace:

En Java, un ejemplo clásico del patrón de decorador es la implementación de Java I/O Streams.

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

4) Así que sí, el "patrón decorador" es un buen candidato para este problema.

Personalmente, preferiría este tipo de solución:

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

5) Sin embargo anotaciones son también una opción. Por ejemplo:

1

Si usted está particularmente interesado en hacer este tipo de cosas con las anotaciones (que no tiene que realmente):

Este ejemplo debe empezar:

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

Aunque esto no resuelve cómo usar las anotaciones como lo desea, en lugar de utilizar el "diseño de decorador", podría proponer utiliza el "diseño del constructor" si se adapta mejor a sus necesidades (parece que sí).

ejemplo de uso rápida:

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

de salida: Cake {azúcar = 0,75, mantequilla = 0,5, huevos = 2, vanila = 2, la harina = 1,5, levadura química = 0,0, leche = 0,5, cereza = 0}

para la aplicación plena y una muy buena explicación, compruebe http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html

+0

Muchas gracias por la información, usar el patrón de construcción es la clave para resolver el problema. Pero aún quiero investigar más si es posible para usar Anotación para resolver el problema. Y también sé que el uso de la anotación tiene un efecto secundario para la memoria. – Crazenezz