Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns Groovy中@Delegate、@Mixin和Traits之间的区别?_Design Patterns_Groovy_Delegates_Mixins_Traits - Fatal编程技术网

Design patterns Groovy中@Delegate、@Mixin和Traits之间的区别?

Design patterns Groovy中@Delegate、@Mixin和Traits之间的区别?,design-patterns,groovy,delegates,mixins,traits,Design Patterns,Groovy,Delegates,Mixins,Traits,有人能解释一下我什么时候想使用vs.Mixin(@Mixin)vs.Delegate(@Delegate)吗?也许一些权衡和设计问题会有所帮助 它们似乎都允许重用多个行为“类”。谢谢。:-) 这个SO线程也很有用:我同意,它们似乎都允许重用多个“类”的行为。不过,两者之间存在差异,而且 了解这些可能有助于你做出决定 在提供每个功能的简要总结/重点介绍以及合适的示例之前 用法,让我们总结一下每种用法的结论 结论/典型用法: @Delegate:用于添加Delegate类的所有功能,但仍避免与 实

有人能解释一下我什么时候想使用vs.Mixin(@Mixin)vs.Delegate(@Delegate)吗?也许一些权衡和设计问题会有所帮助

它们似乎都允许重用多个行为“类”。谢谢。:-)


这个SO线程也很有用:

我同意,它们似乎都允许重用多个“类”的行为。不过,两者之间存在差异,而且 了解这些可能有助于你做出决定

在提供每个功能的简要总结/重点介绍以及合适的示例之前 用法,让我们总结一下每种用法的结论

结论/典型用法:

  • @Delegate:用于添加Delegate类的所有功能,但仍避免与 实际执行情况。让我们来实现你的目标
  • @Mixin:groovy 2.3不推荐使用。将一个或多个类中的方法添加到类中的简单方法。虫子缠身
  • 运行时mixin:将一个或多个方法添加到任何现有类中,例如JDK或第三方库中的类
  • 特性:groovy 2.3中的新特性。定义良好的向类中添加一个或多个特性的方法。替换@Mixin。唯一的 其中之一是添加的方法在Java类中可见
现在,让我们更详细地了解每一个问题

@代表

继承在许多情况下被过度使用。也就是说,它经常被不当使用。Java中的经典示例有 扩展输入流、读取器或集合类。。对于其中的大多数,使用继承是非常困难的 与实现紧密结合。也就是说,实际实现是这样编写的: 公共方法实际上使用另一种方法。如果您同时覆盖这两个选项,并调用
super
,则可能会得到不需要的结果 副作用。如果实现在更高版本中发生更改,则必须更新对的处理 它也是

相反,你应该努力使用

例如,对添加到列表中的元素进行计数的计数列表:

class CountingList<E> {
    int counter = 0
    @Delegate LinkedList<E> list = new LinkedList<>()
    boolean addAll(Collection<? extends E> c) {
        counter += c.size()
        list.addAll(c)
    }
    boolean addAll(int index, Collection<? extends E> c) {
        counter += c.size()
        list.addAll(index, c)
    }
    // more add methods with counter updates
}
总结:

  • 将方法从一个类添加到另一个类中

  • 在groovy中使用您的答案很好,但请注意,这些特性与AST转换(如@CompileStatic)并不正式兼容。非常感谢这个解释得很好的答案!你推荐哪本关于Groovy的书?@AlexanderSuraphel以我的经验,Groovy in Action是一本优秀的书。它不仅深入地展示了Groovy,还非常好地讨论了一般编程概念,以及Groovy如何帮助而不是取代Java来提供一个极其强大的开发环境。Steinar,在你提到的案例中,“钻石问题”是如何处理的?@AlexanderSuraphel:我想晚做总比不做好,有关如何处理钻石问题的说明,请参见。
    class First {
        String hello(String name) { "Hello $name!" }
    }
    
    @Mixin(First)
    class Second {
        // more methods
    }
    
    assert new Second().hello('Vahid') == 'Hello Vahid!'
    
    class MyStringExtension {
        public static String hello(String self) {
            return "Hello $self!"
        }
    }
    
    String.mixin(MyStringExtension)
    
    assert "Vahid".hello() == 'Hello Vahid!'
    
    trait Name {
        abstract String name()
        String myNameIs() { "My name is ${name()}!" }
    }
    trait Age {
        int age() { 42 }
    }
    
    class Person implements Name, Age {
        String name() { 'Vahid' }
    }
    
    def p = new Person()
    assert p.myNameIs() == 'My name is Vahid!'
    assert p.age() == 42
    assert p instanceof Name
    assert p instanceof Age