3

我正在开发一个组件,它应该:

  1. 从某些外部计算组件接收数据(项目集合)。我预计每个请求的输入大约有 100-1K 的项目。

  2. 验证数据,如果缺失,计算一些属性

  3. 持久化数据

大约有十种类型的项目。我使用继承来建模项目。我有一个具有通用属性和计算的基本项目类以及实现类型特定问题的子类。类似于以下示例:

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();
    }
}

有没有更好的方法/模式来完成我的任务?有什么建议吗?

4

3 回答 3

1

您尝试使用的模式相当合理。一般来说,我可能会建议使用接口而不是BaseItem类,因为它可能不包含那么多通用功能。

通常,大多数人似乎建议为要实现的类定义接口。如果您绝对想在 AbstractClass 中共享公共代码,我会推荐实现该接口的类,因为这种模式将在未来提供更大的可扩展性和灵活性。

因此,您首先要定义什么是适合您的项目。对我来说,在您的用例中,一个 Item 似乎是三件事:第一,它必须定义postCalculate()将在所有 Item 上调用的方法。其次,它必须提供一种isValid()方法。第三,它还应该提供一种getName()方法。

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

然后你将开始实现你的 Abstract 类。仅当确实有必要在所有项目之间共享代码库时才这样做。

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;
    }
}

如果 BaseItem.postCalculate() 是所有项目都需要完成的事情,那么这是一个很好的方法。如果您不完全确定,最好在一个HelperTool类中的某处定义一个方法,该方法对项目执行此常见计算,并由以下postCalculate()方法调用:

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

许多人会争辩说,这会给您带来更轻松的时间,因为您的要求BaseItem可能会随着时间的推移而变化。

不管你去哪条路线,现在你只需要定义你的实际项目:

public   class ItemA extends BaseItem {
    BigDecimal value;

    @Override
    public void postCalucate() {
        //some A specific calculations                        
        super.postCalucate();
    }
}
于 2012-10-30T19:54:19.477 回答
1

虽然一般建议是避免过度使用继承,但这并不是过度使用的情况。因此,请继续使用这种方法。

除此之外:您的代码显示封装问题。你不应该拥有所有这些非私有领域。提醒一下:完全没有可见性是包可见性(在整个包和所有子类中可见)。将您的字段设为私有。

于 2012-10-30T19:40:52.090 回答
0

先验地,你的提议似乎是合理的。

但可以肯定的是,您必须查看对象生命周期的所有事件:

  • 实例化
  • 使用,阅读
  • 合作
  • 坚持
  • ...
于 2012-10-30T19:41:58.580 回答