java Java中的装饰器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12065750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Decorator in Java
提问by Crazenezz
I see about decorator examplein Python:
我在 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.
并且对它如何在 Java 中实现感到好奇,所以我搜索并获得了一些使用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:
我如何使用这样的 Java Annotation 像上面的 Python 示例一样制作它:
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 concatenateand how to return it, so the main
method can display the result that has been concatenate.
我在尝试制作样本时遇到了一些问题,问题是我不知道如何将str
值从main
方法传递给BoldWrapper
,ItalicWrapper
因此它可以连接以及如何返回它,因此该main
方法可以显示已连接。
Please advise if there is something wrong with my understanding of annotation.
如果我对注释的理解有问题,请告知。
回答by Strelok
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>
}
}
回答by paulsm4
1) The link you cited is a good one - it does justice to the "Decorator Pattern" with respect to Java. "Design Patterns" themselves, of course, are independent of any particular OO language:
1)您引用的链接是一个很好的链接 - 它对 Java 的“装饰模式”很公平。当然,“设计模式”本身独立于任何特定的面向对象语言:
2) Here is another good link:
2)这是另一个很好的链接:
In Java, a classical example of the decorator pattern is the Java I/O Streams implementation.
在 Java 中,装饰器模式的一个经典示例是 Java I/O 流实现。
FileReader frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);
4) So yes, the "decorator pattern" is a good candidate for this problem.
4) 所以是的,“装饰者模式”是这个问题的一个很好的候选者。
Personally, I would prefer this kind of solution:
就个人而言,我更喜欢这种解决方案:
String myHtml =
new BoldText (
new ItalicText (
new HtmlText ("See spot run")));
5) However annotations are also an option. For example:
5) 然而,注释也是一种选择。例如:
回答by gianglaodai
This is late but I think it may help the other people. From Java 8 with Function interface, we can write something close to python decorator like this:
这已经晚了,但我认为它可能会帮助其他人。从带有 Function 接口的 Java 8 开始,我们可以像这样写一些接近 python 装饰器的东西:
Function<Function<String, String>, Function<String, String>> makebold = func -> input -> "<b>" + func.apply(input) + "</b>";
Function<Function<String, String>, Function<String, String>> makeitalic = func -> input -> "<i>" + func.apply(input) + "</i>";
Function<String, String> helloWorld = input -> "hello world";
System.out.println(makebold.apply(makeitalic.apply(helloWorld)).apply("")); // <b><i>hello world</i></b>
回答by DanielCuadra
Although this doesn't resolve how to use annotations as you wanted, rather than using the "decorator design", I could propose you use the "builder design" if it suits better to your needs (it seems like so).
尽管这并不能解决如何根据需要使用注释,而不是使用“装饰器设计”,但如果它更适合您的需要(似乎是这样),我可以建议您使用“构建器设计”。
Quick usage example:
快速使用示例:
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);
}
}
Output:Cake{sugar=0.75, butter=0.5, eggs=2, vanila=2, flour=1.5, bakingpowder=0.0, milk=0.5, cherry=0}
输出:蛋糕{糖=0.75,黄油=0.5,鸡蛋=2,香草=2,面粉=1.5,发酵粉=0.0,牛奶=0.5,樱桃=0}
For full implementation and a very good explanation, please check http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html
对于完整的实现和很好的解释,请查看 http://javarevisited.blogspot.mx/2012/06/builder-design-pattern-in-java-example.html