Как обрабатывать необязательные переменные объекта в Java? - PullRequest
2 голосов
/ 17 апреля 2010

Для моей торговой программы у меня есть класс Merchant. Данный объект Торговца может иметь или не иметь определенного особого качества или набора особых качеств. Например, один объект Merchant может иметь качество Stockbroker, другой Merchant может иметь качества Financial Services и Stockbroker, а другой Merchant может не иметь никаких специальных качеств вообще.

Моей первоначальной мыслью было создание HashMap и класса Qualities следующим образом:

Map<Qualities, Boolean> merchantQualities = new HashMap<Qualities, Boolean>();

Единственная проблема в том, что у Торговцев есть как минимум 50 возможных специальных качеств, так что было бы чрезвычайно утомительно подклассировать все качества из класса Качества.

Есть ли лучший способ кодирования этих необязательных специальных качеств и представления их в классе Merchants, чем HashMap, и создание подкласса класса Qualities?

Ответы [ 2 ]

10 голосов
/ 17 апреля 2010

Все зависит от того, что такое Qualities и что они делают. Если список достаточно стабилен, enum s может быть хорошим решением:

enum Quality {
  MERCHANT,
  STOCKBROKER,
  ...
}

Хорошая вещь о enum s в том, что они в основном являются классами, поэтому могут реализовывать интерфейсы и иметь состояние и поведение. Они также поставляются с полезными вспомогательными классами:

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

и затем вы можете использовать все функции Set, такие как contains() и т. Д.

Но я не могу сказать вам, подходит ли вам это решение, не зная дополнительной информации.

Редактировать: общая отправная точка для этого во многих языках - enums. В C / C ++ / C # это будет выглядеть примерно так:

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

Вот как лучше перечисления в Java. Допустим, вы определили другое перечисление для типа акций:

enum StockType {
  LISTED_EQUITIES,
  MANAGED_FUNDS
}

Если вы делаете предположение, что данный тип продавца продает один тип вещи:

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

поэтому вместо того чтобы сказать:

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

Вы говорите:

StockType stockType = merchantType.getStockType();

Перечисления Java имеют состояние и поведение . Это чрезвычайно мощная концепция.

Но вы можете сделать лучше, чем это. Вместо того, чтобы предполагать одну акцию на торговца, это лучше обрабатывается поведением:

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

В этот момент ваш код становится:

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

, которое является гораздо более естественным, читаемым и расширяемым решением.

0 голосов
/ 17 апреля 2010

Я думаю, вы можете использовать шаблон декоратора здесь, чтобы украсить своего Продавца различными декораторами (биржевой маклер, финские услуги и т. Д.) Посмотрите на h ttp: //en.wikipedia.org/wiki/Decorator_pattern

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...