Попытка спроектировать объектную модель - используя перечисления - PullRequest
1 голос
/ 27 декабря 2008

Я пытаюсь спроектировать объектную модель (для C #) и не могу найти лучший способ хранения данных. Я попытаюсь использовать простой пример, чтобы проиллюстрировать это!

У меня есть объект «pet», который может быть одним из «cat», «dog» и т. Д. Поэтому я создал класс «pet» с перечислением «petType» для его хранения.

Теперь это то, где это становится сложным. Если «домашнее животное» - это «кошка», то его «пищей» может быть «рыба», «молоко» и т. Д. Если это «собака», то его «пищей» могут быть «мясо», «печенье». или что-то.

Теперь я должен создать большое перечисление для "рыбы", "молока", "мяса" и "печенья" и каким-то образом закодировать его так, чтобы "кошке" нельзя было присвоить "food.meat"? Для моего класса «домашнее животное» не имеет смысла иметь перечисление «catfood» и «dogfood», потому что оно не растяжимо, и в итоге будет храниться множество нулевых перечислений.

Есть ли элегантное решение, которого я не вижу?

Ответы [ 5 ]

2 голосов
/ 27 декабря 2008

Попробуйте №2. Кажется, чтобы быть правильным

interface IPet { }

class Cat : IPet
{
    public void eat(CommonFood food) { }
    public void eat(CatFood food) { }
}

class Dog : IPet
{
    public void eat(CommonFood food) { }
    public void eat(DogFood food) { }
}

interface IFood { }

abstract class CommonFood : IFood { }

abstract class CatFood : IFood { }

abstract class DogFood : IFood { }

class Milk : CommonFood { }

class Fish : CatFood { }

class Meat : DogFood { }

class Program
{
    static void Main(string[] args)
    {
        Dog myDog = new Dog();
        myDog.eat(new Milk()); // ok, milk is common
        myDog.eat(new Fish()); // error
    }
}
0 голосов
/ 03 января 2009

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

Вот один вариант в Ruby.

class CatFood
  attr_reader :items

  def initialize
    @items = ['fish', 'milk']
  end
end

class DogFood
  attr_reader :items

  def initialize
    @items = ['meat', 'biscuits']
  end
end

class NoFood
  attr_reader :items

  def initialize
    @items = []
  end
end

class Pet
  attr_reader :food

  def initialize(food)
    @food = food
  end
end

class PetFactory
  def create_dog
    Pet.new(DogFood.new)
  end

  def create_cat
    Pet.new(CatFood.new)
  end

  def create_unknown_pet
    Pet.new(NoFood.new)
  end
end
0 голосов
/ 28 декабря 2008

Я согласен с Tautologistics в отношении наличия подкласса Cat и Dog Pet (или реализации интерфейса Pet!) Вместо того, чтобы иметь явное перечисление PetType и поле. Явные «флаги типа» не соответствуют действительности с ОО-дизайном.

Что касается продовольственных отношений, вы можете рассмотреть возможность реализации двух концепций:

  1. «Бизнес-правило» для питомца, реализованное методом acceptsFood(FoodEnum food). Этот метод будет отвечать за проверку законности при назначении пищи.
  2. Свойство «любимая еда» любого экземпляра Pet (подкласса), позволяющее отдельному питомцу идентифицировать любимую еду (из набора продуктов, которые фактически принимаются его видом).
0 голосов
/ 27 декабря 2008

я не знаю о вашей кошке, но мои кошки едят мясо и совсем немного!

и съедать столовые отходы, такие как печенье, вредно для собак (и кошек)

но это в сторону, почему ты крутишься с перечислениями? и почему у вашего объекта 'pet' есть свойство 'petType'? Простым / прямым представлением был бы класс Pet с подклассами Cat и Dog, но более практичным представлением был бы интерфейс Pet , который можно применять к любому объекту Animal .

0 голосов
/ 27 декабря 2008

Во-первых, кошка и собака , вероятно, должны быть подклассами из питомец Предполагая, что есть некоторые общие свойства всех питомцев.

Далее, мне неясно, что вы планируете делать с food . В качестве объектной модели домашнее животное содержит тип пищи или будут методы, такие как еда , которые будут принимать еда в качестве аргумента?

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