简体   繁体   English

是否继承

[英]Inheritance or not

I am working on a component which is supposed to: 我正在研究一个应该是:

  1. receive data (collection of items) from some external calculation component. 从一些外部计算组件接收数据(项目集合)。 I expect about 100-1K of items on input on each request. 我希望每个请求输入大约100-1K的项目。

  2. validate data, calculate some attributes if missing 验证数据,如果丢失则计算一些属性

  3. persist data 坚持数据

There are about ten types of items. 大约有十种类型的物品。 I use inheritance to model items. 我使用继承来建模项目。 I have a base item class with common attributes and calculations and subclasses implementing type specific problems. 我有一个基本项类,它具有公共属性和计算以及实现类型特定问题的子类。 Similar to following example: 与以下示例类似:

public abstract class BaseItem {
    String name;
    boolean valid = true;

    public void postCalucate() {
        //common calculation
                    valid = valid && (name != null);
    }
}

public   class ItemA extends BaseItem {
    BigDecimal value;

    @Override
    public void postCalucate() {
        //some A specific calculations                        
        super.postCalucate();
    }
}

public   class ItemA1 extends ItemA {
    BigDecimal extraValue;

    @Override
    public void postCalucate() {
        //some A1 subtype specific calculations
               valid = isA1ItemValid();
        super.postCalucate();
    }
}

public   class ItemB extends BaseItem {
    Integer size;

    @Override
    public void postCalucate() {
        //some B specific calculations
        super.postCalucate();
    }
}

Is there any better way/pattern to do my task? 有没有更好的方法/模式来完成我的任务? Any advices? 有什么建议吗?

While the general advice is to avoid over-usage of inheritance, this is no case of over-usage. 虽然一般建议是避免过度使用继承,但这不是过度使用的情况。 So, go ahead with this approach. 所以,继续这种方法。

Apart from that: Your code shows problems with encapsulation. 除此之外:您的代码显示封装问题。 You shouldn't have all these non-private field. 你不应该拥有所有这些非私人领域。 As a reminder: no visibility at all is package-visibility (visible in the whole package and to all sub-classes). 提醒一下: 根本没有可见性是包可见性(在整个包和所有子类中都可见)。 Make your fields private. 将您的字段设为私有。

The pattern you are trying to use is fairly sound. 您尝试使用的模式非常合理。 In general, I would probably suggest the use of an interface instead of a BaseItem class, since it might not contain that much common functionality. 一般来说,我可能会建议使用接口而不是BaseItem类,因为它可能不包含那么多常见功能。

In general, most people seem to recommend defining interfaces for your classes to implement. 通常,大多数人似乎建议为要实现的类定义接口。 If absolutely you want to share common code in an AbstractClass, I would recommend that class implementing the interface, since this pattern would lend itself to greater extensibility and flexibility in the future. 如果绝对想要在AbstractClass中共享公共代码,我建议实现该接口的类,因为这种模式将来可以提供更大的可扩展性和灵活性。

As such, you would first begin by defining what an Item is for you. 因此,您首先要定义一个项目适合您。 For me, it seems that an Item is three things in your use case: one, it must define the postCalculate() method that will be called on all Items. 对我来说,似乎一个Item在你的用例中是三件事:一,它必须定义将在所有Items上调用的postCalculate()方法。 Second, it must provide an isValid() method. 其次,它必须提供一个isValid()方法。 And third, it should also provide a getName() method. 第三,它还应该提供getName()方法。

public interface Item {
    void postCalucate();
    boolean isValid();
    String getName();
}

Then you would begin implementing your Abstract class. 然后,您将开始实现您的Abstract类。 Do this only if it really is necessary to share a codebase between all your items. 只有在您需要在所有项目之间共享代码库时才这样做。

public abstract class BaseItem implements Item {
    String name;
    boolean valid = true;

    public void postCalucate() {
        //common calculation
        valid = valid && (name != null);
    }

    public boolean isValid() { 
        return valid; 
    }

    public String getName() {
        return name;
    }
}

If BaseItem.postCalculate() is something that will need to be done for all items, this is a good way to do it. 如果BaseItem.postCalculate()是需要为所有项目完成的事情,这是一个很好的方法。 If you're not entirely sure, it might be a good idea instead to define a method somewhere in a Helper or Tool class that performs this common calculation for items, and is called by the postCalculate() methods: 如果你不完全确定,那么在HelperTool类中的某个地方定义一个方法来执行常见的项计算,并由postCalculate()方法调用可能是个好主意:

public class ItemTools {
    public static boolean meetsRequirements(Item item) {
        return item.isValid && item.getName() != null;
    } 
}

This, many would argue, gives you an easier time as your requirements on BaseItem may change over time. 许多人认为,这会让您更容易,因为您对BaseItem的要求可能会随着时间的BaseItem而发生变化。

Regardless of which route you go there, now you'll just have to define your actual items: 无论你去哪条路线,现在你只需要定义你的实际物品:

public   class ItemA extends BaseItem {
    BigDecimal value;

    @Override
    public void postCalucate() {
        //some A specific calculations                        
        super.postCalucate();
    }
}

A priori, your proposal seems reasonable. 先验,你的提议似乎是合理的。

But to be sure, you have to look at all the events of the life cycle of your objects: 但可以肯定的是,您必须查看对象生命周期的所有事件:

  • instantiation 实例
  • use, read 使用,阅读
  • collaboration 合作
  • persistence 坚持
  • ... ...

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

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