Search code examples
javaoopdesign-patternspolymorphismmixins

Working with subclasses that have different method names without violating SOLID principles


//interfaces

public interface Singer{
    void sing();
}
public interface SongWriter{
    void writeSong();
}

//Implementations

public class PureSinger implements Singer{
    void sing(){}
}
public class SingerSongWriter implements Singer, SongWriter{
    void sing(){}
    void writeSong(){}
}

//Client code

void methodA(){
    Singer objPureSinger = new PureSinger();
    Singer objSingerSWer = new SingerSongWriter();

    doSomething(objPureSinger);
    doSomething(objSingerSWer);
}

public void doSomething(Singer obj){
    obj.sing();
    obj.writeSong();    //<--- this does not work.
}

In order to acheve this type of code, how should I design the class structure?


Solution

  • In order to acheve this type of code, how should I design the class structure?

    Start by defining an interface called Artist that has a single method called perform. Next, define two subclasses namely Singer and SongWriter each implementing perform and containig the code to sing a song and write a song respectively.

    The following two design-patterns would support your use-case really well :

    1. The Decorator design pattern : In your case, Artist is the Component, Singer and SongWriter are Concrete Components and ArtistDecorator is your Abstract Decorator class. Use the ArtistDecorator to wrap a Singer into a SongWriter. The doSomething method takes an Artist parameter and is passed the final decorated Artist object that wraps a Singer into a SongWriter.
    2. The Composite design pattern : In your case Arist is the Component. CompositeArtist is the Composite and Singer and SongWriter are the Leaf or the Concrete Component classes. The doSomething method takes an Artist parameter. Pass it an instance of the CompositeArtist (which IS-A Artist) and doSomething simply calls perform which internally iterates through all the Artist instances calling their perform method one by one.