开发者

How to handle optional variables of an object in Java?

For my trading program, I have a Merchant class. A given Merchant object may or may not have a particular special quality or bundle of special qualities. For example, one Merchant object may have the Stockbroker quality, another Merchant may have the Financial Services and Stockbroker qualities, and another Merchant may have no special qualities at all.

My initial thought was to create a HashMap and a Qualities class as follows:

Map<Qualities,开发者_StackOverflow Boolean> merchantQualities = new HashMap<Qualities, Boolean>();

The only problem is, there are at least 50 possible special qualities for Merchants, such that it would be extremely tiresome to subclass all the qualities from the Quality class.

Is there a better way of coding for these optional special qualities and representing them in the Merchants class than a HashMap and subclassing a Qualities class?


This all depends on what Qualities are and what they do. If the list is fairly stable, enums can be a good solution:

enum Quality {
  MERCHANT,
  STOCKBROKER,
  ...
}

The good thing about enums is they basically are classes so the can implement interfaces and have state and behaviour. They also come with useful helper classes:

Set<Quality> = EnumSet.of(MERCHANT, STOCKBROKER);

and then you can use all the Set functions like contains() etc.

But I can't tell you if this is an appropriate solution for you without knowing more information.

Edit: a common starting point for this in many languages is enums. In C/C++/C# this would go something like:

if (merchantType == STOCKBROKER) { ... }

Here's how Java's enums are better. Let's say you define another enum for stock type:

enum StockType {
  LISTED_EQUITIES,
  MANAGED_FUNDS
}

If you make the assumption a given merchant type sells one type of thing:

enum MerchantType {
  STOCKBROKER(StockType.LISTED_EQUITIES),
  FINANCIAL_ADVISER(StockType.MANAGED_FUNDS);

  private final StockType stockType;

  MerchantType(StockType stockType) {
    this.stockType = stockType;
  }

  public StockType getStockType() {
    return stockType;
  }
}

so instead of saying:

StockType stockType;
if (merchantType == MerchantType.STOCKBROKER) {
  stockType = StockType.EQUITIES;
}
...

you say:

StockType stockType = merchantType.getStockType();

Java enums have state and behaviour. That's an extremely powerful concept.

But you can do better than this. Instead of assuming one stock per merchant, this is better handled by behaviour:

enum MerchantType {
  STOCKBROKER,
  FINANCIAL_ADVISER;

  private static final Map<MerchantType, Set<StockType>> STOCK_TYPES;

  static {
    STOCK_TYPES = new EnumSet<MerchantType, Set<StockType>>(MerchantType.class);
    STOCK_TYPES.put(STOCKBROKER, EnumSet.of(StockType.LISTED_EQUITIES));
    STOCK_TYPES.put(FINANCIAL_ADVISER,
      EnumSet.of(StockType.LISTED_EQUITIES, StockType.MANAGED_FUNDS));
  }

  public boolean canSell(StockType stockType) {
    Set<StockType> stockTypes = STOCK_TYPES.get(this);
    return stockTypes != null && stockTypes.contains(stockType);
  }
}

at which point your code becomes:

if (merchantType.canSell(StockType.LISTED_EQUITIES)) {
  ...
}

which is a far more natural, readable and extensible solution.


I think you can use the decorator pattern over here to decorate your Merchant with various decorators (stockbroker, fin services. etc.) Have a look at http://en.wikipedia.org/wiki/Decorator_pattern

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜