Which design pattern to use while refactoring two classes containing half related and half unrelated functions? - oop

I have two objects, Bird and Dog. Bird and Dog have identical implementations for about 50% of methods/properties but different unrelated methods and properties for the other 50%.
I'm refactoring and I don't know what is the best strategy.
I tried defining a superclass Animal to implement common methods in the superclass and let the children classes define their own methods/properties.
I wrote a factory that returned one or the other - this all seems right... but I'm confused when writing the calling code.. e.g.
public class Animal{
public string Talk(){ return "yak yak yak";
}
public class Dog:Animal{
public string Walk(){ return "walk walk walk"; }
}
public class Bird:Animal{
public string Fly(){ return "flap flap flap"; }
}
...
Animal thing = CreatureFactory.GetCreature(modifier);
When I want to use thing to Talk there's no problem,
Debug.Print(thing.Talk());
but what about when as the programmer I know I want it to Fly do I cast it to Bird? That seems wrong... but defining a Fly method on Dog seems wrong too.

You either cast it to a bird:
Debug.Print(((Bird)thing).Fly());
or you treat it as a bird the whole time:
// depending on how the factory works, might not need the cast
Bird thing = (Bird) CreatureFactory.GetCreature(modifier);
Debug.Print(bird.Fly());

Given your example, when you want your Animal to fly, the class doing the flying is working with the wrong class -- it should be using the Bird itself or some ICanFly interface.
While the other answers said you can do it with casting, the readability of your code will suffer because of it. When you have factories creating your objects, there's absolutely no reason you should be casting those objects to another type. There's also a solid argument that your classes are violating the Single Responsibility Principle when you start casting to other types.

The way I would approach it is to have the factory method return a concrete type rather than the superclass. You can still pass it to methods that can operate on the superclass, but you have an item of the concrete class to work with when needed and don't need to cast it.
Bird bird = CreatureFactory.GetBird();
or
Dog dog = CreatureFactory.GetDog();
Now, you can still use them as an Animal.
public class Trainer
{
public void TeachToSpeak( Animal animal )
{
...
animal.Talk();
}
}
But since they are typed to the concrete class, you can make use of the methods they don't share as appropriate.

I would say:
if your dog has also a methods that gives the idea of "movement", I would change the name of fly and walk to "move" and then call it.
If your dog doesn't have anything like that, the dev shouldn't be able to call it on an anymal object, because not all animals can fly :)

For one thing, I would put a virtual method on the base class called Move() and override it in the derived classes.
(The following is C#)
public abstract class Animal {
public string Talk() { return "yak yak yak"; }
public virtual string Move();
}
public class Dog : Animal {
public override string Move() { return "walk walk walk"; }
}
public class Bird : Animal {
public override string Move() { return "flap flap flap"; }
}
But to answer your question, if you want the animal to move if (and only if) it can fly, you could define an IFlyingAnimal interface and implement it with Bird. Then you can test whether an Animal implements that interface. If it does, cast it to IFlyingAnimal and call its Fly() method.
public interface IFlyingAnimal {
string Fly();
}
public class Bird : Animal, IFlyingAnimal {
public string Fly(){ return "flap flap flap"; }
}
//later, in your main program
public string FlyIfYouCan(Animal animal) {
if (animal is IFlyingAnimal)
return ((IFlyingAnimal)animal).Fly();
return "I can't fly!";
}
You don't have to use an interface; you could just use if (animal is Bird) instead. But it's much better practice to do it this way; birds aren't the only animals that can fly, so you're making the decision based on what your item does, not what it is. That's what interfaces are for.

Related

General code design: shared and alternating patterns

The situation
My question applies to all programming languages with classes and inheritance. Im sure the answer is out there somewhere already, but I could not find it as i don’t have the right terminology to use.
Lets take the classic example. We got Dogs and Cats which are both of the type Animal:
abstract class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
Simple enough. Some behavior is shared in the Animal class, anything that differs between Cat and Dog is coded in their respective classes.
Now suppose we got 2 planets. Earth and Mars. Both planets have Cats and Dogs. But, behavior for all animals on Earth differs from all animals on Mars. They, for example, experience a difference in gravity which affects the way they move.
There is no difference between specific animal types between the planets. Thus, all differences between animals on Earth and Mars can be coded at the parent level, that of the Animal class.
Not only that, but some behavior is available for all Animal instances on Mars that does not exist on Earth.
Ideally, in code dealing with these animals, we deal with a MarsAnimal or EarthAnimal class that is implemented by either a Dog or Cat. The implementing code does not need to know if they are Dogs or Cats. It does already know on what planet the Animal lives though.
What I thought about already
One solution would be the following:
abstract class Animal {
}
abstract class Cat extends Animal {
}
abstract class Dog extends Animal {
}
interface MarsAnimal {
}
interface EarthAnimal {
}
class MarsCat extends Cat implements MarsAnimal {
}
class MarsDog extends Dog implements MarsAnimal {
}
class EarthCat extends Cat implements EarthAnimal {
}
class EarthDog extends Dog implements EarthAnimal {
}
Ofc, the obvious problem with this is, that any behavior specific to MarsAnimal would need to be implemented in both the MarsCat and MarsDog classes. That’s ugly code duplication and definitely not what I was looking for.
The only semi-acceptable method I could think of was the following:
abstract class Animal {
private PlanetAnimal planetAnimal;
public function myBehavior() {
this.planetAnimal.myBehavior();
}
}
class Cat extends Animal {
}
class Dog extends Animal {
}
interface PlanetAnimal {
function myBehavior();
}
class MarsAnimal implements PlanetAnimal {
public function myBehavior() {
// marsAnimal- specific behavior here
}
}
class EarthAnimal implements PlanetAnimal {
public function myBehavior() {
// earthAnimal- specific behavior here
}
}
Thus, when creating a Cat or Dog instance, since we know what planet they are from at that point in the code, we give them the needed PlanetAnimal instance in their constructor (either MarsAnimal or EarthAnimal).
This is close. The only problem with this is, like I said, some behavior exists only for all animals on Mars. I’d have to still implement a method in both the Animal and PlanetAnimal classes that is used only for Mars. If this is the only solution then sure, but it feels like there should be some better method out there.
So, any ideas? I’d love to hear!
Edit 1
Based on questions, a small clarification: the main problem here is how to implement shared behavior between many different categories. There is shared behavior:
between all animals on all planets;
between all animals on a specific planet;
between all animals of a specific type (i.e. Cat or Dog), irrespective of what planet they are on
Edit 2
I work mainly in Java and PHP. This question specifically was asked after I encountered this in PHP, though I know I had similar situations in Java too. I know, for PHP, my first proposed solution could work in combination with Traits. That might even be where I end up. But, everywhere online I saw people warning against the use of Traits, saying it is almost always/ always bad code design. That's why I'm searching for the best solution
The solution you are looking for is a design pattern called the Strategy pattern. The pattern is defined as follows:
The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
In your case, the Animal class would be the context, and the PlanetAnimal class would be the strategy. The context would be responsible for delegating to the correct strategy for each concrete implementation. In your example, the context would be the Animal class, and the strategy would be the PlanetAnimal class. The context would be responsible for delegating to the correct strategy for each concrete implementation.
Something like this, in Python:
class Animal:
def __init__(self, animalStrategy):
self.animalStrategy = animalStrategy
def walking(self):
raise NotImplementedError()
class Cat(Animal):
def walking(self):
return self.animalStrategy.walking(canJump=True, canFly=False, canSwim=False, speed=10)
class Bird(Animal):
def walking(self):
return self.animalStrategy.walking(canJump=True, canFly=True, canSwim=False, speed=20, walkSpeed=2)
class MarsAnimalStrategy:
def walking(self, canJump, canFly, canSwim, speed):
return f"walking on Mars with speed {speed}"
class EarthAnimalStrategy:
def walking(self, canJump, canFly, canSwim, speed, walkSpeed):
return f"walking on Earth with speed {speed} and walkSpeed {walkSpeed}"
marsCat = Cat(MarsAnimalStrategy())
marsCat.walking()
earthCat = Cat(EarthAnimalStrategy())
earthCat.walking()
In this way, the Animal class is not responsible for knowing how to walk on Mars or Earth, but instead delegates that responsibility to the strategy. The strategy is responsible for knowing how to walk on Mars or Earth. The context/"user" is responsible for delegating to the correct strategy for each concrete instance.
I wouldn't go into details, but consider using a composition of objects instead of class inheritance. In short, each descendant class of Animal would have to be fully tested, including an internal behavior of a parent class, and Animal could easily become a God Object, which is not a good thing. Alternatively:
class IAnimal: # Python have only classes, but consider it as an interface
def walking(self):
raise NotImplementedError()
def eating(self):
raise NotImplementedError()
# etc.
class Cat(IAnimal):
def __init__(self, physicalBody, livingEntity):
self.physicalBody = physicalBody
self.livingEntity = livingEntity
def walking(self):
direction = self.livingEntity.goalDirection()
if self.physicalBody.canMove(direction):
self.physicalBody.move(direction)
return self.livingEntity.movedTo(self.physicalBody.position)
return self.livingEntity.wasFrustrated()
Now Cat is responsible only for its own behavior, and PhysicalBody and LivingEntity are responsible for their own behavior. This way, you can easily test each class separately, and you can easily replace PhysicalBody and LivingEntity with other implementations, without changing Cat class. I would repeat, that now Cat class is highly focused solely on its own behavior and implementation of IAnimal interface/contract. Now, of course, you need to type self.physicalBody.canMove(direction) instead of self.canMove(direction), but it's a small price to pay for a better design. Differences in the behavior of Earth and Mars animals would now be represented by different implementations of LivingEntity classes, that could share some common parts.

Multiple Inheritance: What's a good example?

I'm trying to find a good example for the use of multiple inheritance what cannot be done with normal interfaces.
I think it's pretty hard to find such an example which cannot be modeled in another way.
Edit: I mean, can someone name me a good real-world example of when you NEED to use multiple inheritance to implement this example as clean as possible. And it should not make use of multiple interfaces, just the way you can inherit multiple classes in C++.
The following is a classic:
class Animal {
public:
virtual void eat();
};
class Mammal : public Animal {
public:
virtual void breathe();
};
class WingedAnimal : public Animal {
public:
virtual void flap();
};
// A bat is a winged mammal
class Bat : public Mammal, public WingedAnimal {
};
Source: wiki.
One example where multiple class inheritance makes sense is the Observer pattern. This pattern describes two actors, the observer and the observable, and the former wants to be notified when the latter changes its object state.
A simplified version for notifying clients can look like this in C#:
public abstract class Observable
{
private readonly List<IObserver> _observers = new List<IObserver>();
// Objects that want to be notified when something changes in
// the observable can call this method
public void Subscribe(IObserver observer)
{
_observers.Add(observer);
}
// Subclasses can call this method when something changes
// to notify all observers
protected void Notify()
{
foreach (var observer in _observers)
observer.Notify();
}
}
This basically is the core logic you need to notify all the registered observers. You could make any class observable by deriving from this class, but as C# does only support single class inheritance, you are limited to not derive from another class. Something like this wouldn't work:
public class ImportantBaseClass { /* Members */ }
public class MyObservableSubclass : ImportantBaseClass, Observable { /* Members */ }
In these cases you often have to replicate the code that makes subclasses observable in all of them, basically violating the Don't Repeat Yourself and the Single Point of Truth principles (if you did MVVM in C#, think about it: how often did you implement the INotifyPropertyChanged interface?). A solution with multiple class inheritance would be much cleaner in my opinion. In C++, the above example would compile just fine.
Uncle Bob wrote an interesting article about this, that is where I got the example from. But this problem often applies to all interfaces that are *able (e.g. comparable, equatable, enumerable, etc.): a multiple class inheritance version is often cleaner in these cases, as stated by Bertrand Meyer in his book "Object-Oriented Software Construction".

Abstract class and methods

i have Abstract class
Public class Abstract baseClass
{
public abstract string GetString();
public abstract string GetString1();
}
public class DerivedClass : baseClass
{
public override string GetString()
{
return "test data";
}
public override string GetString1()
{
throw new NotImplementedException();
}
}
In above line of code, i have to implement both abstract method in derived class. But due to some reason i don't want to implement all methods, just one of them like GetString() only. How can it be done?
Thanks
If DerivedClass is going to offer common functionality to other classes, you can mark it as abstract, implement one of the methods here, and then inheritors will only have to implement the remaining method.
If you aren't going to support the other method in a given implementation, you still have to expose the method in your class, but similar to what you have here, you would typically throw a NotSupportedException. For void methods, you could simply return (do nothing).
Finally, if you want to separate out the things that have both methods and those that have only one, you can use interfaces.
public interface IBase
{
string GetString();
}
public interface IBasePlus : IBase
{
string GetStringPlus();
}
You can have one class that implements IBasePlus, but you can supply this to methods that take a parameter of type IBase, in which case you won't see the extra method.
Generally, if you don't implement all the abstract methods then your new class is also an abstract class. To get a concrete class, you need all the methods to be implemented. If you only want/need to implement a subset of the methods, consider using multiple interfaces (one interface with GetString and another with GetString1) rather than an abstract class. Then you can just implement the interfaces with the methods you want to use in the class.
Take the abstract keyword off the other method and provide a default implementation in the base class

Why does Wikipedia say "Polymorphism is not the same as method overloading or method overriding."

I have looked around and could not find any similar question.
Here is the paragraph I got from Wikipedia:
Polymorphism is not the same as method overloading or method overriding. Polymorphism is only concerned with the application of specific implementations to an interface or a more generic base class. Method overloading refers to methods that have the same name but different signatures inside the same class. Method overriding is where a subclass replaces the implementation of one or more of its parent's methods. Neither method overloading nor method overriding are by themselves implementations of polymorphism.
Could anyone here explain it more clearly, especially the part "Polymorphism is not the same as method overriding"? I am confused now. Thanks in advance.
Polymorphism (very simply said) is a possibility to use a derived class where a base class is expected:
class Base {
}
class Derived extends Base {
}
Base v = new Derived(); // OK
Method overriding, on the other hand, is as Wiki says a way to change the method behavior in a derived class:
class Shape {
void draw() { /* Nothing here, could be abstract*/ }
}
class Square extends Shape {
#Override
void draw() { /* Draw the square here */ }
}
Overloading is unrelated to inheritance, it allows defining more functions with the same name that differ only in the arguments they take.
You can have polymorphism in a language that does not allow method overriding (or even inheritance). e.g. by having several different objects implement the same interface. Polymorphism just means that you can have different concrete implementations of the same abstract interface. Some languages discourage or disallow inheritance but allow this kind of polymorphism in the spirit of programming with abstractions.
You could also theoretically have method overriding without polymorphism in a language that doesn't allow virtual method dispatch. The effect would be that you could create a new class with overridden methods, but you wouldn't be able to use it in place of the parent class. I'm not aware of any mainstream language that does this.
Polymorphism is not about methods being overridden; it is about the objects determining the implementation of a particular process. An easy example - but by no means the only example - is with inheritance:
A Novel is a type of Book. It has most of the same methods, and everything you can do to a Book can also be done to a Novel. Therefore, any method that accepts a Book as an argument can also deal with a Novel as an argument. (Example would include .read(), .write(), .burn()). This is, per se, not referring to the fact that a Novel can overwrite a Book method. Instead, it is referring to a feature of abstraction. If a professor assigns a Book to be read, he/she doesn't care how you read it - just that you do. Similarly, a calling program doesn't care how an object of type Book is read, just that it is. If the object is a Novel, it will be read as a Novel. If it is not a novel but is still a book, it will be read as a Book.
Book:
private void read(){
#Read the book.
}
Novel:
private void read(){
#Read a book, and complain about how long it is, because it's a novel!
}
Overloading methods is just referring to having two methods with the same name but a different number of arguments. Example:
writeNovel(int numPages, String name)
writeNovel(String name)
Overloading is having, in the same class, many methods with the same name, but differents parameters.
Overriding is having, in an inherited class, the same method+parameters of a base class. Thus, depending on the class of the object, either the base method, or the inherited method will be called.
Polymorphism is the fact that, an instance of an inherited class can replace an instance of a base class, when given as a parameters.
E.g. :
class Shape {
public void draw() {
//code here
}
public void draw(int size) {
//this is overloading
}
}
class Square inherits Shape {
public void draw() {
//some other code : this is overriding
}
public void draw(color c) {
//this is overloading too
}
}
class Work {
public myMethod(Shape s) {
//using polymophism, you can give to this method
//a Shape, but also a Square, because Square inherits Shape.
}
}
See it ?
Polymorphing is the fact that, the same object, can be used as an instance of its own class, its base class, or even as an interface.
Polymorphism refers to the fact that an instance of a type can be treated just like any instance of any of its supertypes. Polymorphism means 'many forms'.
Say you had a type named Dog. You then have a type named Spaniel which inherits from Dog. An instance of Spaniel can be used wherever a Dog is used - it can be treated just like any other Dog instance. This is polymorphism.
Method overriding is what a subclass may do to methods in a base class. Dog may contain a Bark method. Spaniel can override that method to provide a more specific implementation. Overriding methods does not affect polymorphism - the fact that you've overriden a Dog method in Spaniel does not enable you to or prevent you from treating a Spaniel like a dog.
Method overloading is simply the act of giving different methods which take different parameters the same name.
I hope that helps.
Frankly:
Polymorphism is using many types which have specific things in common in one implementation which only needs the common things, where as method overloading is using one implementation for each type.
When you override a method, you change its implementation. Polymorphism will use your implementation, or a base implementation, depending on your language (does it support virtual methods?) and depending on the class instance you've created.
Overloading a method is something else, it means using the same method with a different amount of parameters.
The combination of this (overriding), plus the possibility to use base classes or interfaces and still call an overriden method somewhere up the chain, is called polymorphism.
Example:
interface IVehicle
{
void Drive();
}
class Car : IVehicle
{
public Drive() { /* drive a car */ }
}
class MotorBike : IVehicle
{
public Drive() { /* drive a motorbike */ }
}
class Program
{
public int Main()
{
var myCar = new Car();
var myMotorBike = new MotorBike();
this.DriveAVehicle(myCar); // drive myCar
this.DriveAVehicle(myMotorBike); // drive a motobike
this.DriveAVhehicle(); // drive a default car
}
// drive any vehicle that implements IVehicle
// this is polymorphism in action
public DriveAVehicle(IVehicle vehicle)
{
vehicle.Drive();
}
// overload, creates a default car and drives it
// another part of OO, not directly related to polymorphism
public DriveAVehicle()
{
// typically, overloads just perform shortcuts to the method
// with the real implemenation, making it easier for users of the class
this.DriveAVehicle(new Car());
}
}

What is composition as it relates to object oriented design?

I hear (and read on this site) a lot about "favour composition over inheritance".
But what is Compositon? I understand inheritance from the point of Person : Mammal : Animal, but I can't really see the definition of Compostion anywhere.. Can somebody fill me in?
Composition refers to combining simple types to make more complex ones. In your example, composition could be:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal::Animal:
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person::Mammal:
string firstName
string lastName
If you wanted to go totally composition (and get rid of all inheritance) it would look like this:
Animal:
Skin animalSkin
Organs animalOrgans
Mammal:
private Animal _animalRef
Hair/fur mammalFur
warm-blooded-based_cirulation_system heartAndStuff
Person:
private Mammal _mammalRef
string firstName
string lastName
The advantage to this approach is that the types Mammal and Person do not have to conform to the interface of their previous parent. This could be a good thing because sometimes a change to the superclass can have serious effects on the subclasses.
They still can have access to the properties and behaviours of these classes through their private instances of these classes, and if they want to expose these former-superclass behaviours, they can simply wrap them in a public method.
I found a good link with good examples here: http://www.artima.com/designtechniques/compoinh.html
Composition is simply the parts that make up the whole. A car has wheels, an engine, and seats. Inheritance is a "is a " relationship. Composition is a "has a" relationship.
There are three ways to give behavior to a class. You can write that behavior into the class; you can inherit from a class that has the desired behavior; or you can incorporate a class with the desired behavior into your class as a field, or member variable. The last two represent forms of code reuse, and the final one - composition - is generally preferred. It doesn't actually give your class the desired behavior - you still need to call the method on the field - but it puts fewer constraints on your class design and results in easier to test and easier to debug code. Inheritance has its place, but composition should be preferred.
class Engine
{
}
class Automobile
{
}
class Car extends Automobile // car "is a" automobile //inheritance here
{
Engine engine; // car "has a" engine //composition here
}
Composition - Functionality of an object is made up of an aggregate of different classes. In practice, this means holding a pointer to another class to which work is deferred.
Inheritance - Functionality of an object is made up of it's own functionality plus functionality from its parent classes.
As to why composition is preferred over inheritance, take a look at the Circle-ellipse problem.
An example of Composition is where you have an instance of a class within another class, instead of inheriting from it
This page has a good article explaining why people say "favour composition over inheritance" with some examples of why.
composition
simply mean using instance variables that are references to other objects.
For an illustration of how inheritance compares to composition in the code reuse department, consider this very simple example:
1- Code via inheritance
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple extends Fruit {
}
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
When you run the Example1 application, it will print out "Peeling is appealing.", because Apple inherits (reuses) Fruit's implementation of peel(). If at some point in the future, however, you wish to change the return value of peel() to type Peel, you will break the code for Example1. Your change to Fruit breaks Example1's code even though Example1 uses Apple directly and never explicitly mentions Fruit.
for more info ref
Here's what that would look like:
class Peel {
private int peelCount;
public Peel(int peelCount) {
this.peelCount = peelCount;
}
public int getPeelCount() {
return peelCount;
}
//...
}
class Fruit {
// Return a Peel object that
// results from the peeling activity.
public Peel peel() {
System.out.println("Peeling is appealing.");
return new Peel(1);
}
}
// Apple still compiles and works fine
class Apple extends Fruit {
}
// This old implementation of Example1
// is broken and won't compile.
class Example1 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
2- Code via composition
Composition provides an alternative way for Apple to reuse Fruit's implementation of peel(). Instead of extending Fruit, Apple can hold a reference to a Fruit instance and define its own peel() method that simply invokes peel() on the Fruit. Here's the code:
class Fruit {
// Return int number of pieces of peel that
// resulted from the peeling activity.
public int peel() {
System.out.println("Peeling is appealing.");
return 1;
}
}
class Apple {
private Fruit fruit = new Fruit();
public int peel() {
return fruit.peel();
}
}
class Example2 {
public static void main(String[] args) {
Apple apple = new Apple();
int pieces = apple.peel();
}
}
for more information ref