Некоторые snarks являются boojums: список boojums или свойство is_boojum на всех snarks?

В предметной области имеется большая совокупность названных snarks. Некоторые из snarks являются буджумами.

Существует всего два способа моделирования этого:

// as a property: 
 class Snark { 
 string name; 
 bool is_boojum; 
 }; 
// as a list:
 class Snark { 
 typedef long Id;
 Id id;
 string name;
 }; 
 tree<snark::id> boojums;
</snark::id>

Кажется интуитивным, что если бы мы определили, что snarks бывают у мужчин и женщин, мы добавим свойство "sex" к определению класса snark; и если бы мы определили, что все, кроме пяти snarks, были побежденными субъектами, мы составили список членов королевской семьи.

Существуют ли принципы, которые можно применить, или это вопрос архитектурных предпочтений?

6 ответов

Я считаю, что информационная энтропия, связанная с классификацией, может быть руководством к тому, какой метод использовать. Классификации с низкой энтропией (т.е. Большинство объектов имеют одинаковое значение) предлагают реализацию списка, отслеживающую исключительные случаи, в то время как классификации с высокой энтропией (вы не можете делать какие-либо очень хорошие прогнозы о том, какая классификация будет иметь объект) предлагают реализацию свойства.


Какую проблему вы пытаетесь решить?

Если целью записи королевской власти snarks является отображение короны на головах в графическом интерфейсе, тогда имеет смысл просто быть атрибутом. (В качестве альтернативы, может быть подкласс RoyalSnark с переопределенным методом Render.)

Если цель состоит в том, чтобы быстро найти все королевские snarks, тогда список более подходит - в противном случае вам нужно будет посмотреть на каждый snark и проверить его атрибут.


Как производный класс:

class Snark 
{
 virtual void Approach(Creature& approacher) {};
};
class Boojum : public Snark
{
 virtual void Approach(Creature& approacher) 
 { 
 approacher.softlySuddenlyVanishAway(); 
 }
};


Естественный способ сделать это кажется во всех случаях свойством.

Вы можете использовать список для производительности или оптимизировать пространство. Обе причины поражают меня как потенциальные случаи преждевременной оптимизации, прерывания инкапсуляции и/или хранения избыточных данных с последующим риском отсутствия целостности (потому что я все же должен был бы сам запросить сам объект, чтобы выяснить, является ли он королевским - я должен 'нужно знать, что это свойство обрабатывается особым образом по причинам производительности). Вы могли бы скрыть реализацию списка за получателем, чтобы заставить его вести себя как свойство.

Кроме того, если эти объекты были сохранены в БД, проблема с производительностью в значительной степени уходит, поскольку уровень БД может создать список во время выполнения с использованием запроса в любом случае.


Если вы спрашиваете о моделировании базы данных, то наиболее просто рассмотреть is_boojum как столбец атрибута в таблице Snarks. Если вам нужно искать все буиумы, запрос прост:

SELECT * FROM Snarks WHERE is_boojum = 1

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

Но ваш вопрос касался моделирования, а не оптимизации.


Хммм. Моя первая мысль состоит в том, что, действительно, Буджем является подтипом Снарка. но спецификация, по-видимому, возражает против этого, поскольку "snark был буджем, вы видите". Ну, это означает, что snark is_a Boojum, и это сделает граф наследования циклическим. Не может быть этого.

С другой стороны, я не думаю, что есть указание, что Snark может стать Boojum; либо это Boojum, либо нет.

Я думаю, возможно, вы хотите, чтобы Boojum mixin -

abstract class Snark { /*...*/ };
class PlainSnark extends Snark {/*...*/};
class RoyalSnark extends Snark implements Boojum {/*...*/};

licensed under cc by-sa 3.0 with attribution.