简体   繁体   English

不同子类中的相同实现

[英]Same implementation in different subclasses

Say I have the following scenario: 说我有以下情况:

    abstract class A {
        abstract method1();
        abstract method2();
    }

    class B extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 3
        }
    }

    class C extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 4
        }
    }

    class D extends A {
        method1() {
            // implementation 2
        }
        method2() {
            // implementation 4
        }
    }

Bottom line: several subclasses of the same class, using different method implementations for different methods. 底线:同一类的几个子类,对不同的方法使用不同的方法实现。

The problem is that I have the same implementation in different subclasses. 问题是我在不同的子类中具有相同的实现。 My question is what to do with these common implementations? 我的问题是如何处理这些常见的实现?
The logical way to do it would be to create another level of abstraction but that only works if I have one method with common implementations (since Java doesn't have multiple inheritence). 做到这一点的逻辑方法是创建另一个抽象级别,但是只有在我使用一种具有通用实现的方法时才有效(因为Java没有多重继承)。 I could also put the implementation most commonly used in the superclass and only implement it differently in the other classes. 我还可以将最常用的实现放在超类中,而仅在其他类中以不同的方式实现。 However, I wouldn't do that because in time the most common implementation might change with the addition of other classes, and besides, I'd like to keep the methods abstract in the superclass. 但是,我不会这样做,因为随着时间的推移,最常见的实现可能会随着其他类的添加而发生变化,此外,我想将方法​​抽象化为超类。

Is there some pattern that would solve my problem in an "elegant manner"? 是否有某种模式可以“优雅地”解决我的问题?

You're running into the classic OOP issue with inheritance heirarchies becoming unwieldy :-) 您正在遇到经典的OOP问题,继承层次结构变得笨拙:-)

My suggested solutions: 我建议的解决方案:

  • Prefer composition to inheritance - factor out the implementations into separate objects that can be "plugged in" to provide the required behaviour. 首选组合而不是继承 -将实现分解为单独的对象,可以“插入”这些对象以提供所需的行为。 The methods in your base class just call the implementation plugin via its defined interface. 基类中的方法仅通过其定义的接口调用实现插件。 This is basically the Strategy Pattern . 这基本上是策略模式 It's a very solid approach, though can sometimes become prone to a lot of over-engineering / boilerplate when you have a lot of different strategy types. 这是一个非常可靠的方法,但是当您有许多不同的策略类型时,有时可能会出现很多过度设计/样板的情况。
  • Adopt a prototype-based model - use prototype-based objects rather than traditional OOP. 采用基于原型的模型 -使用基于原型的对象,而不是传统的OOP。 This solves all the problems - you escape the inherent restrictions of inheritance hierarchies and can just copy the implementation you want to whichever objects need it at runtime. 这就解决了所有问题-您摆脱了继承层次结构的固有限制,可以将所需的实现复制到运行时需要的任何对象。 This is the most radical option, but can bring some big benefits. 这是最根本的选择,但可以带来一些好处。
  • Factor implementations out into static functions - this way you can share the implementations - it's a bit messy since you still need to do all the overrides, but they just become one-liners delegating the call to the right implementation. 将实现分解为静态函数 -通过这种方式可以共享实现-有点混乱,因为您仍然需要执行所有替代,但是它们只是将对正确实现的调用委派给您。 This is often the least intrusive option. 这通常是侵入性最小的选项。

I would recommend Composition. 我会建议组成。 Consider the following: 考虑以下:

interface I1 {
     method1();
}

abstract class A implements I1{
    abstract method1();
    abstract method2();
}

class CommonOperations implements I1 {
    method1() {
        // implementation 1
    }
}

class B extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 3
    }
}

class C extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 4
    }
}

class D extends A {
    method1() {
        // implementation 2
    }
    method2() {
        // implementation 4
    }
}

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

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