Skip to main content
Improved spelling, punctuation, wording, capitalization, and syntax highlighting.
Source Link

What is provable about Animal? youYou don't provide code or return type, Presumablypresumably something like:

Is it still true for Cat? Yes. (assuming you add the state changes).

What about that type checking statement in Cat though? thisThis looks bad, itsit's not a LSP violation, but it does raise questions about whether Food has a violation in it. If it doesn't, then I shouldn't need to check the Type right?

Really, the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type.

I'm going to use c#C#, which has a "flaw" in that you cantcan't specify what exceptions might be thrown in the class defintiondefinition. That being the case, and respecting the normal rule about not using exceptions for logic, I will try to avoid all exceptions.

Obviously, this isntisn't the only way to do this, itsit's just a way to avoid your code smell and problems with exceptions.

public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}
public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}

What is proveableprovable?

public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}
public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}

Now you have avoided all exceptions and LSP questions, you can extend youyour food types indefinitely, although you may have issues if you add more AnimalType enums. It would be important to make sure that that list is complete at the start.

What is provable about Animal? you don't provide code or return type, Presumably something like:

Is it still true for Cat? Yes. (assuming you add the state changes)

What about that type checking statement in Cat though? this looks bad, its not a LSP violation, but it does raise questions about whether Food has a violation in it. If it doesn't then I shouldn't need to check the Type right?

Really the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type.

I'm going to use c#, which has a "flaw" in that you cant specify what exceptions might be thrown in the class defintion. That being the case, and respecting the normal rule about not using exceptions for logic, I will try to avoid all exceptions.

Obviously this isnt the only way to do this, its just a way to avoid your code smell and problems with exceptions.

public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}

What is proveable?

public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}

Now you have avoided all exceptions and LSP questions, you can extend you food types indefinitely, although you may have issues if you add more AnimalType enums. It would be important to make sure that that list is complete at the start

What is provable about Animal? You don't provide code or return type, presumably something like:

Is it still true for Cat? Yes (assuming you add the state changes).

What about that type checking statement in Cat though? This looks bad, it's not a LSP violation, but it does raise questions about whether Food has a violation in it. If it doesn't, then I shouldn't need to check the Type right?

Really, the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type.

I'm going to use C#, which has a "flaw" in that you can't specify what exceptions might be thrown in the class definition. That being the case, and respecting the normal rule about not using exceptions for logic, I will try to avoid all exceptions.

Obviously, this isn't the only way to do this, it's just a way to avoid your code smell and problems with exceptions.

public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}

What is provable?

public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}

Now you have avoided all exceptions and LSP questions, you can extend your food types indefinitely, although you may have issues if you add more AnimalType enums. It would be important to make sure that that list is complete at the start.

added 60 characters in body
Source Link
Ewan
  • 79.9k
  • 5
  • 83
  • 179
public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}
public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}
public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}
public class Cat : Animal
{
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}
public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public readonly AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}
public class Cat : Animal
{
    public Cat() { this.Type = AnimalType.Carnivore; }
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}
added 1738 characters in body
Source Link
Ewan
  • 79.9k
  • 5
  • 83
  • 179

Really the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type. The correct design would seem

Edit: it seems the correct design is in scope...

I'm going to fall outsideuse c#, which has a "flaw" in that you cant specify what exceptions might be thrown in the scope ofclass defintion. That being the case, and respecting the normal rule about not using exceptions for logic, I will try to avoid all exceptions.

Obviously this isnt the only way to do this, its just a way to avoid your question thoughcode smell and problems with exceptions.

public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}

What is proveable?

Eat always returns a type of Food 
IsEdibleBy always returns true or false
AnimalType is one of the enum values

Now we add Cat:

public class Cat : Animal
{
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}

Now you have avoided all exceptions and LSP questions, you can extend you food types indefinitely, although you may have issues if you add more AnimalType enums. It would be important to make sure that that list is complete at the start

Really the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type. The correct design would seem to fall outside the scope of your question though.

Really the code smell is pointing out that Food should have some sort of FoodType property or CanBeEatenBy(Animal animal) method, rather than using SubTypes to identify the type.

Edit: it seems the correct design is in scope...

I'm going to use c#, which has a "flaw" in that you cant specify what exceptions might be thrown in the class defintion. That being the case, and respecting the normal rule about not using exceptions for logic, I will try to avoid all exceptions.

Obviously this isnt the only way to do this, its just a way to avoid your code smell and problems with exceptions.

public enum AnimalType
{
    Omnivore,
    Herbivore,
    Carnivore
}

public class Food
{
    public bool IsEdibleBy(Animal a)
    {
        return true;
    }
}

public class EatenFood
{
    public override bool IsEdibleBy(Animal a)
    {
        return false;
    }
}

public class Animal
{
    public AnimalType Type = AnimalType.Omnivore;
    public Food Eat(Food f)
    {
         if(f.IsEdibleBy(this))
         {
              return new EatenFood(f);
         }
         else
         {
              return f;
         }
    }
}

What is proveable?

Eat always returns a type of Food 
IsEdibleBy always returns true or false
AnimalType is one of the enum values

Now we add Cat:

public class Cat : Animal
{
}

Public class Meat : Food
{
   public override bool IsEdibleBy(Animal a)
   {
       return a.Type == AnimalType.Omnivore || 
              a.Type == AnimalType.Carnivore;
   }
}

Now you have avoided all exceptions and LSP questions, you can extend you food types indefinitely, although you may have issues if you add more AnimalType enums. It would be important to make sure that that list is complete at the start

Source Link
Ewan
  • 79.9k
  • 5
  • 83
  • 179
Loading