首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在显示异构项列表时应采取何种设计方法

在显示异构项列表时应采取何种设计方法
EN

Stack Overflow用户
提问于 2011-05-20 11:36:12
回答 5查看 379关注 0票数 7

让我们想象一下,我想在一个表中显示一个库存项列表(使用Java)。域模型由抽象基类StockItem组成,其他各种类型的库存项都是从该类派生的。StockItem提供了一个最小的接口(getId()和getDescription()),但除此之外,子类可能有很大的变化。

如果我将自己限制在StockItem上定义的方法上,我将无法向用户提供足够的详细信息,因此这意味着某些列将引用不适用于某些行的字段(例如,物理商品是可数的,此计数应该出现在表中,而服务项(也将出现在表中)是不可计数的,在这种情况下,应该显示"N/A“或类似的内容)。

为了坚持“可数”的例子,在我看来,似乎有几个解决方案(但请记住,可数不是唯一涉及的接口)。

  1. 使可数接口成为基类的一部分,并强制所有东西都是可数化的,即使它们不是。对于没有意义的类,它们需要返回一些特殊值或抛出异常,或者以其他方式表示它们正在破坏StockItem的契约。
  2. 在我的迭代器中,使用大量实例的检查和适当的强制转换。如果我引入了一个新的StockItem子类,或者以其他方式更改了继承树,那么我必须记住修改这段代码。

这两种方法对我来说都像是反模式,我很想听听可能采取的任何更优雅的方法。我怀疑这并不是灵丹妙药,但如果其他语言的特性使这类事情变得更容易,我也会有兴趣听到它们(不过,出于普遍的兴趣,我不会很快重新实现这个系统:)

谢谢你,菲尔

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-05-20 13:50:06

适配器模式

在StockItem类中添加一个方法:

代码语言:javascript
复制
/**
 * Adapt the current instance to the type
 * denoted by clazz else return null
 * ...
 */
public <T> T adapt(Class<T> clazz){
    if( clazz.isInstance(this)){
        return (T)this;
    }
    return null;
}

这将由所有子类继承,并允许调用方安全地转换类型.不要被泛型延迟,它只是说我希望这个方法返回一个与clazz参数相同类型的实例。

现在,您的表提供程序可以实现如下内容:

代码语言:javascript
复制
public String getColumnText(Object cell, int columnIndex) {
    if (cell instanceof StockItem) {
        StockItem item = (StockItem) cell;

        switch(columnIndex) {
            case ID:
                return item.getID;
            case DESCRIPTION:
                return item.getDescription;
            case COUNT:
            Countable countableItem = item.adapt(Countable.class);
                return countableItem == null ? "N/A" : countableItem.getCount();
        }
    }
    return "N/A";
}
票数 3
EN

Stack Overflow用户

发布于 2011-05-20 11:51:39

首先是一个表模型类,类似于表中每个列都有一个字段的bean。该类的实例可以很容易地显示。

然后我会介绍一个接口

代码语言:javascript
复制
public interface TableModelAdapter {   // bad name - this is not the adapter pattern...
  public TableModel getTableModel();
}

并使StockItem实现了该接口。StockItem将实现一些默认行为,所有子类都将向表模型中的字段添加一些内容:

代码语言:javascript
复制
public class Book {

  // ..

  @Override
  public TableModel getTabelModel {
    TableModel model = super.getTableModel();  // the initial one with default entries
    model.setTitle(this.title);                // like: a book can display a title
    return model;
   }
}
票数 1
EN

Stack Overflow用户

发布于 2011-05-20 12:34:23

作为一个非常简单的解决方案,您可以添加一个方法:

代码语言:javascript
复制
/**
* Get key/value for all fields in the right order.
*/
public SortedPairRepresentation getPairRepresentation(){
  // For example one might use a SortedSet<Pair<String,String,>> pairs
  // that sort on the key (lexicographically or in a custom order 
  // s.th. IDs and description are always first). Or you just rely
  // on StockItem and its Subclasses to return them in the correct order.
  // It's up to you.
}

我承认这不是表的POV中最优雅的版本,但至少它是一种对域对象有意义并且对域对象的其他客户端没有副作用的方法。

如果不强制执行排序顺序,可能会更清楚,但当必须显示大量元素时,这可能会非常有用,因为以排序的方式创建元素可以确保在表中显示它们,只需简单地遍历每对表示形式即可完成。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6071339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档