让我们想象一下,我想在一个表中显示一个库存项列表(使用Java)。域模型由抽象基类StockItem组成,其他各种类型的库存项都是从该类派生的。StockItem提供了一个最小的接口(getId()和getDescription()),但除此之外,子类可能有很大的变化。
如果我将自己限制在StockItem上定义的方法上,我将无法向用户提供足够的详细信息,因此这意味着某些列将引用不适用于某些行的字段(例如,物理商品是可数的,此计数应该出现在表中,而服务项(也将出现在表中)是不可计数的,在这种情况下,应该显示"N/A“或类似的内容)。
为了坚持“可数”的例子,在我看来,似乎有几个解决方案(但请记住,可数不是唯一涉及的接口)。
这两种方法对我来说都像是反模式,我很想听听可能采取的任何更优雅的方法。我怀疑这并不是灵丹妙药,但如果其他语言的特性使这类事情变得更容易,我也会有兴趣听到它们(不过,出于普遍的兴趣,我不会很快重新实现这个系统:)
谢谢你,菲尔
发布于 2011-05-20 13:50:06
适配器模式
在StockItem类中添加一个方法:
/**
* 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参数相同类型的实例。
现在,您的表提供程序可以实现如下内容:
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";
}发布于 2011-05-20 11:51:39
首先是一个表模型类,类似于表中每个列都有一个字段的bean。该类的实例可以很容易地显示。
然后我会介绍一个接口
public interface TableModelAdapter { // bad name - this is not the adapter pattern...
public TableModel getTableModel();
}并使StockItem实现了该接口。StockItem将实现一些默认行为,所有子类都将向表模型中的字段添加一些内容:
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;
}
}发布于 2011-05-20 12:34:23
作为一个非常简单的解决方案,您可以添加一个方法:
/**
* 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中最优雅的版本,但至少它是一种对域对象有意义并且对域对象的其他客户端没有副作用的方法。
如果不强制执行排序顺序,可能会更清楚,但当必须显示大量元素时,这可能会非常有用,因为以排序的方式创建元素可以确保在表中显示它们,只需简单地遍历每对表示形式即可完成。
https://stackoverflow.com/questions/6071339
复制相似问题