Лучший шаблон для таблицы поиска с разными внутренними представлениями? Образец наблюдателя?

Я пишу свой собственный класс LookupTable, который получает на входе

  • карта ключевых точек и соответствующих значений RGB

OR

  • 3 канала (красный, зеленый, синий), и в каждом канале есть ключевые точки для этого канала и соответствующие значения в этих ключевых точках для красного, зеленого и синего цветов.

Класс LookupTable может быть построен по-разному, из разных структур данных. Я храню 3 внутренние структуры данных:

1. map<point, pixel>
2. vector<pixel> 
3. struct my{
    map<float, value> red; 
    map<float, value> green;  
    map<float, value> blue; }

Класс LookupTable может быть построен из 1 или 3, а 2 всегда вычисляется, поэтому "зависит" от них.

Проблемы:

  1. как узнать, из какой структуры данных (1 или 3) мне следует рассчитывать 2?
  2. если сначала заполнено 1, затем заполнено 3, как отслеживать, что происходит в моем классе? Шаблон наблюдателя кажется излишним ...
  3. простое решение - использовать несколько логических значений - нехорошо, сложно поддерживать и добавлять новые представления данных в будущем, даже я это понимаю.
  4. Идеально,

construct(map<point, pixel>) OR

construct(struct my)

нужно выполнить только один раз, а в другой раз он вызывается - просто верните значение

(Эти методы используются вместо конструкторов, которые являются частными)


person Saskia    schedule 05.03.2014    source источник


Ответы (1)


У вас должен быть только один способ делать что-то в вашей реализации. Нет необходимости хранить разные структуры для достижения одной и той же цели. Просто представьте пользователю два фасада через свой публичный API.

Предполагая, что pixel выглядит примерно так (предупреждение о псевдокоде):

class pixel{
  float red, green, blue;
  pixel(float, float, float);
  float getRed();
  ...
}

Затем ваша таблица LookupTable (кстати, ужасное имя ... ColourPanel или что-то в этом роде было бы более наглядным):

class LookupTable{
  std::map<point, pixel> pointColours;
  void colourThePoint(point, pixel);
  void colourThePoint(point, float, float, float);
  // the pixel returned gives them "getRed" "getGreen" etc... 
  // So Don't Repeat Yourself (DRY) by replicating that functionality here.
  pixel getThePointColout(point); 
  void applyManipulation(std::function<void(pixel)> manip) {
    std::for_each( pointColours.begin(), pointColours.end(), manip );
  }
  ...
 }

НА ОСНОВЕ ВАШИХ КОММЕНТАРИЙ Я добавил способ применения функции манипулирования к элементам. Эта функция манипуляции может выглядеть примерно так:

void colourMePurple( pixel& original ){
   pixel.increaseBlue(32).increaseRed(32).decreaseGreen(32);
}

И будет использоваться так:

LookupTable myColours;
...
myColours.applyManipulation(colourMePurple);
person Dennis    schedule 05.03.2014
comment
Причина, по которой я сохраняю и 1. map ‹point, pixel› И 3. struct my {map ‹float, value› red; map ‹float, value› green; map ‹float, value› blue; } заключается в том, что внутри этих каналов могут быть разные правила / математические функции для каждого канала, чтобы расти - линейно, ‹некоторые функции› и т. д. - person Saskia; 05.03.2014
comment
@Oleksandra См. Мое предложение по преодолению вашей потребности в манипуляциях с пикселями. - person Dennis; 05.03.2014