简体   繁体   English

避免代码重复的良好做法 Java

[英]Good practice to avoid code duplication Java

I have an specification interface lets call it Spec and two classes that implement it lets call them ImpA and ImpB .我有一个规范接口,我们称之为Spec和两个实现它的类,我们称之为ImpAImpB It worked great until I realized that few methods from ImpA and impB share the same implementation.它工作得很好,直到我意识到ImpAimpB中很少有方法共享相同的实现。 I have tried to avoid it by declaring methods in Spec with default and implementing them right in it, but I'm sure that there is a better way to do it.我试图通过在Spec中声明默认方法并在其中实现它们来避免它,但我确信有更好的方法来做到这一点。 Maybe some design pattern?也许一些设计模式?

If the code that's duplicated doesn't use the state of the class (the instance variables), putting the code in a default method in the interface is one solution.如果重复的代码不使用 class 的 state(实例变量),则将代码放在接口中的默认方法中是一种解决方案。

For more complex situations where you need to access class instance variables, you can create an additional abstract class with the common code.对于需要访问 class 实例变量的更复杂情况,您可以使用通用代码创建额外的抽象 class。 Then ImpA and ImpB would extend the abstract class.然后ImpAImpB将扩展抽象 class。

Collections in Java use a bit of both. Java 中的 Collections 两者都使用了一点。 For example, ArrayList and LinkedList extend AbstractList , which implements List , which contains a few default methods.例如, ArrayListLinkedList扩展了AbstractList ,它实现了List ,其中包含一些默认方法。

While you could make them default methods as you've proposed, another potential solution is to use the Delegation design pattern.虽然您可以按照您的建议将它们设为default方法,但另一个潜在的解决方案是使用委托设计模式。 This means having a fourth class that is entirely for the purpose of separating the common logic.这意味着有第四个 class 完全用于分离公共逻辑。 If that logic needs values to operate then they should be injected into the delegate to allow it to operate (and be tested) independently.如果该逻辑需要值来操作,那么它们应该被注入到委托中以允许它独立地操作(并被测试)。

Personally, I find code that prefers delegation over composition to be more elegant, more testable and much more 'refactorable'.就个人而言,我发现更喜欢委托而不是组合的代码更优雅、更可测试且更“可重构”。 But, like many other design questions, there are many varied and valid opinions on this.但是,就像许多其他设计问题一样,对此有许多不同且有效的意见。

interface Spec { 
    void method();
}

class Imp1 implements Spec {
    private final Delegate delegate;

    public Imp1() {
        this.delegate = new Delegate(...);
    }

    public void method() {
        delegate.setContext(...);
        delegate.method();
    }
}

You can make Spec a superclass and have ImpA and ImpB the subclasses.您可以将 Spec 设为超类,并将 ImpA 和 ImpB 设为子类。 You can find more information on the JavaDoc您可以在 JavaDoc 上找到更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM