new trick

May. 25th, 2007 05:26 pm
juan_gandhi: (Default)
[personal profile] juan_gandhi
I wonder how obvious or how stupid or how ubiquitous is the following trick:

Say, I have an enum somewhere outside of my realm:
enum DataType { 
  PERSONAL,  COMMUNITY, PRISON, ARMY;
};

....





and my method takes an instance of that enum, and I really do not like switching based on the enum; of course I can have an
EnumMap
, but the funny trick is that my strategies are based on this enum type, so I can do just this:
enum Strategy { 
  PERSONAL {
    public void process(Entity entity) {...};
  }, 
  COMMUNITY {
    public void process(Entity entity) {...};
  }, 
  PRISON {
    public void process(Entity entity) {...};
  }, 
  ARMY {
    public void process(Entity entity) {...};
  }

  abstract public void process(Entity entity);
  DEFAULT{
    public void process(Entity entity) {...};
  };

  abstract public void process(Entity entity);

(and so on, add functionality here )

  Strategy forDataType(DataType type) {
    Strategy candidate = valueOf(type.name());
    return candidate == null ? DEFAULT : candidate;
  }
};
....


Strategy.forDataType(myType).process(myEntity);




(PURPLE STUFF ADDED LATER)


Is not it a poetry? :)

Date: 2007-05-26 02:39 pm (UTC)
From: [identity profile] furia-krucha.livejournal.com
Я имел в виду, что этого не обнаруживают статические проверки, производимые компилятором (т.е. системой типизации). Конечно, "вручную" можно доказать корректность этого кода, но только как часто придётся проводить это доказательство (и как узнать, что его нужно повторить?)? Статическая типизация для того и существует, чтобы _гарантировать_ отсутствие некоторого класса ошибок. Отказываясь от неё, вы этот класс возвращаете и должны с ним бороться какими-то другими методами.

Date: 2007-05-26 05:33 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Это верно. Но как быть, как статически проверить такую вещь? Ведь нужно новые языковые штуки вводить.

Date: 2007-05-26 05:53 pm (UTC)
From: [identity profile] furia-krucha.livejournal.com
Никак. Если используется такая сильная рефлексия, что тип или значение получается по его имени (строке), которая есть результат (в общем случае произвольного) вычисления, то типизация эквивалентна проблеме остановки. Т.е. в тривиальном случае, вроде данного, assert может и поможет, но вообще --- нет.

Date: 2007-05-26 06:40 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Да дело не в имени. Концептуально они оба зовутся по имени. Но как имплементировать это соответствие? Явно прописать map?

Date: 2007-05-26 08:25 pm (UTC)
From: [identity profile] http://users.livejournal.com/d_m_/
Насколько я понимаю, Вас очень восхищает то, что элемент enum содержит в качестве одного из полей своё имя, и Вам непременно хочется придумать на этой основе какой-нибудь трюк. Однако, назначение этого поля (IMHO) - реализация toString() и некая сериализация/десериализация, где почему-то не хотят использовать порядковые номера.

Date: 2007-05-26 10:01 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Блин. Ну умные же люди собрались. На хера бы мне это восхищение наличием.

Вот задача. Есть независимая сущность, данная нам в именах. В принципе, юзеру пофиг, строки это, числа, набор сингтонов. Просто есть набор, он ограничен и неизменен.

Теперь, юзеру нужно запрограммировать действия, зависящие от этих самых сущностей. Если бы функции были законными элементами языка, и если бы нужно было типа по паре функций на сущность, то можно было бы ограничиться двумя таблицами. Скажем, как на джаваскрипте:
var processMap = {
  PERSON:    function(Entity entity) { /* do this and that */ },
  COMMUNITY: function(Entity entity) { /* do that and then this */ },
etc
};



Но в условиях отсутствия нужно что-то придумывать. Окей, Map<DataType, Strategy> - ну и? Ведь по сути-то дела, нужно быть готовым переварить все входные варианты.

Какие идеи?

Date: 2007-05-26 10:24 pm (UTC)
From: [identity profile] http://users.livejournal.com/d_m_/
> Ведь по сути-то дела, нужно быть готовым переварить все входные варианты.

Обсуждаемый юзер точно знает, какой тип на какую стратегию отображается, ибо он сам эти стратегии и кодирует. Следовательно, речь идёт вовсе не обо "всех входных вариантах", которым несть числа, и где было бы полезно некое автоматизированное нахождение соответствия, как у Вас с совпадающими именами enum.

Что мы вообще обсуждаем - как изящно записать это отображение, используя только синтаксис Java (т.е. конфигурационные файлы не годятся)?


Date: 2007-05-26 09:16 pm (UTC)
From: [identity profile] furia-krucha.livejournal.com
Ну как, добавить в DataType новый метод

Strategy getStrategy(void)

и реализовать его очевидным образом для каждого значения. Потом

data.getStrategy().process(entity);

Всё статически типизировано. Насколько я понимаю, вам нужно решение, которое не меняет DataType ("I have an enum somewhere outside of my realm"), но это по сути значит, что просто нет общего дизайна.

Date: 2007-05-26 09:49 pm (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Если бы в DataType можно было что-то добавить, проблем было бы меньше. Но этот DataType, скажем, принадлежит java.lang.something.

Ну даже если бы. DataType не должен никакого понятия иметь о своих будущих юскейсах. Мало ли кто где использует; на всяк чих не наздоровкаешься.

Date: 2007-05-27 08:07 pm (UTC)
From: [identity profile] furia-krucha.livejournal.com
Если связь между Data и Strategy слабая, т.е не хочется, чтобы Data от неё зависел, то логично использовать Visitor pattern.

Date: 2007-05-28 05:10 am (UTC)
From: [identity profile] ivan-gandhi.livejournal.com
Вот это очень реальная, правильная, хорошая и здоровая альтератива. Не всегда она лучше, чем маппинг, но не всегда и хуже. Надо, наверное, на эту тему подробно что-то написать.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

May 2025

S M T W T F S
    1 2 3
456 7 8 9 10
11 121314151617
181920 21 222324
25 262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 28th, 2025 10:44 pm
Powered by Dreamwidth Studios