我正在尝试设计一个对象模型(用于C#),并且无法找出存储数据的最佳方法。我将尝试用一个简单的例子来说明这一点!
我有一个对象“pet”,可能是“cat”,“dog”等等。所以我创建了一个带有“petType”枚举的“pet”类来存储它。
现在这就变得棘手了。如果“宠物”是“猫”,那么它的“食物”可能是“鱼”,“牛奶”等。如果它是“狗”,那么它的“食物”可能是“肉”,“饼干”什么的。
现在我应该为“鱼”,“牛奶”,“肉”和“饼干”创建一个大的枚举,并以某种方式编码,以便“猫”不能分配“food.meat”? 对于我的“宠物”类来说,有一个“catfood”和“dogfood”枚举是没有意义的,因为那不可扩展,它最终会存储大量的枚举枚举。
有没有一个优雅的解决方案,我没有看到?
答案 0 :(得分:2)
尝试#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
}
}
答案 1 :(得分:0)
首先, cat 和 dog 应该可以从 pet < em> ,假设所有宠物都有一些共同属性。
接下来,我不清楚你打算用 食物 做些什么。作为对象模型, 宠物 会持有一种食物,或者会有 eat 这样的方法把 食物 作为参数?
答案 2 :(得分:0)
我不知道你的猫,但是我的猫吃了很少的肉!
和吃饼干一样吃饼干对狗(和猫)不好
但除此之外,你为什么要搞砸枚举?为什么你的'pet'对象有'petType'属性?简单/直接表示将是具有Cat和Dog子类的Pet类,但更实用的表示形式是可以应用于任何 Animal 对象的Pet 接口。 / p>
答案 3 :(得分:0)
我同意Tautologistics关于拥有Cat和Dog子类Pet(或实现Pet接口!),而不是拥有明确的PetType枚举和字段。明确的“类型标志”与真正的OO设计不一致。
至于食物关系,你可以考虑实施两个概念:
acceptsFood(FoodEnum food)
方法实现。此方法将负责检查食品分配的合法性。Pet
(子类)实例的“最喜欢的食物”属性,允许个体宠物识别出最喜欢的食物(在其物种实际接受的食物中)。答案 4 :(得分:0)
听起来你需要将猫/狗食作为一种策略,并使用一个简单的工厂与适当的宠物一起制作适当的食物。
以下是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