【问题标题】:Trying to design an object model - using enums尝试设计对象模型 - 使用枚举
【发布时间】:2008-12-27 18:46:52
【问题描述】:

我正在尝试设计一个对象模型(用于 C#),但无法找到存储数据的最佳方式。我将尝试用一个简单的例子来说明这一点!

我有一个对象“pet”,它可以是“cat”、“dog”等其中之一。所以我创建了一个带有“petType”枚举的“pet”类来存储它。

现在这就是棘手的地方。如果“宠物”是“猫”,那么它的“食物”可以是“鱼”、“牛奶”等。如果它是“狗”,那么它的“食物”可以是“肉”、“饼干”什么的。

现在我应该为“fish”、“milk”、“meat”和“biscuits”创建一个大枚举并以某种方式对其进行编码,以便不能将“cat”分配给“food.meat”吗? 我的“宠物”类有一个“catfood”和“dogfood”枚举真的没有意义,因为那是不可扩展的,它最终会存储大量为空的枚举。

有没有我看不到的优雅解决方案?

【问题讨论】:

    标签: c# oop enums


    【解决方案1】:

    尝试 #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
        }
    }
    

    【讨论】:

      【解决方案2】:

      首先,catdog 应该是 pet 的子类em>,假设所有宠物都有一些共同的属性。

      接下来,我不清楚你打算用 food 做什么。作为一个对象模型,宠物是否持有某种食物,或者是否会有诸如之类的方法以 food 作为论据?

      【讨论】:

        【解决方案3】:

        我同意同义反复论让 Cat 和 Dog 子类化 Pet(或实现 Pet 接口!),而不是拥有明确的 PetType 枚举和字段。显式的“类型标志”与真正的 OO 设计格格不入。

        关于食物关系,你可以考虑实现两个概念:

        1. Pet 上的“业务规则”,通过acceptsFood(FoodEnum food) 方法实现。此方法将负责检查食物分配的合法性
        2. 任何Pet(子类)实例的“最喜欢的食物”属性,允许个体宠物识别最喜欢的食物(在其物种实际接受的食物集中)。

        【讨论】:

          【解决方案4】:

          我不了解你的猫,但我的猫只吃肉,几乎不吃其他东西!

          吃饼干之类的餐桌残渣对狗(和猫)有害

          但除此之外,你为什么要搞乱枚举?为什么你的“宠物”对象有一个“宠物类型”属性?一个简单/直接的表示是具有 Cat 和 Dog 子类的 Pet 类,但更实际的表示是可以应用于任何 Animal 对象的 Pet interface

          【讨论】:

            【解决方案5】:

            听起来您需要将猫/狗粮视为一种策略,并使用简单的工厂将适当的食物与适当的宠物组合在一起。

            这是 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
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-06-30
              • 2018-05-02
              • 1970-01-01
              • 1970-01-01
              • 2014-02-28
              • 2011-02-24
              相关资源
              最近更新 更多