I am having a difficulty in understanding how to use composition and interface together to favor composition instead of inheritance? An example could be:
Interface:
public interface IMachine {
void TurnOn();
void TurnOff();
}
Machine Class is the parent Class of Printer Class
public class Machine {
protected boolean isOn;
public Machine(boolean isOn) {
this.isOn = isOn;
}
public void TurnOn() {
isOn = true;
System.out.println("Machine is on !");
}
public void TurnOff() {
isOn = false;
}
}
Now if I create a Printer Class which implements IMachine interface, it will implement the methods of the IMachine interface. But let's say I create a Clock Class that implements IMachine interface, then I have to implement those methods again.Is there a more efficient way where we use composition and interface and delegate the methods to Machine class?
With inheritance, you'd have a base class with shared logic, and subclasses using that shared logic. Any public method of that base class is shared API.
With composition, the interface defines the shared API, each implementing class (those that were subclasses before) will delegate those call to a composite class that actually has the shared logic.
Inheritance
public abstract class Machine {
public void turnOn() {/*logic here*/}
public void turnOff() {/*logic here*/}
}
public final class Heater extends Machine {
// heater methods here
}
Composition
public interface Machine {
void turnOn();
void turnOff();
}
final class MachineImpl {
public void turnOn() {/*logic here*/}
public void turnOff() {/*logic here*/}
}
public final class Heater implements Machine {
private MachineImpl impl = new MachineImpl();
#Override public void turnOn() { this.impl.turnOn(); }
#Override public void turnOff() { this.impl.turnOff(); }
// heater methods here
}
Users of Machine will still see the same public API, and users of Heater will still see the same public API, but the logic has been relocated.
This allows Heater to implement multiple independent "features", something that wasn't possible when using inheritance.
Composition is generally referred to in a "has a" relationship. In this case, composition could be used if you had the concept of a PowerSwitch object, for instance. This would be fulfilled in the notice that a Machine "has a" PowerSwitch.
Inheritance is more often referred to as an "is a" relationship, as in your Printer "is a" Machine case.
Using a PowerSwitch object, you could encompass the functionality for both a Printer and a Clock, possibly in an AbstractMachine
public abstract class AbstractMachine implements IMachine {
private PowerSwitch machinePowerSwitch;
public void turnOff() {
machinePowerSwitch.turnOff();
}
public void turnOn() {
machinePowerSwitch.turnOn();
}
public void isOn() {
return machinePowerSwitch.getPowerState();
}
}
Or something similar to that. Printer and Clock could then both extend AbstractMachine.
EDIT: Re-reading the question I see you want composition INSTEAD OF inheritance (I was reading it as you were wanting to use both). In that case, simply use the powerswitch directly in the Printer/Clock classes.
Related
I'm implementing observer pattern in the following way:
interface Layer{
void adjustString(Set<String> strings);
}
interface NotifiableLayer extends Layer{
void layerAdjusted(Layer layer);
}
abstract class ObservableLayer implements Layer{
Set<NotifiableLayer> observers = new HashSet<>();
void addObserver(NotifiableLayer layer){
observers.add(layer);
}
void removeObserver(NotifiableLayer layer){
observers.remove(layer);
}
void notifyObservers(){
observers.forEach(l -> l.layerAdjusted(this));
}
}
class MyLayer extends ObservableLayer{
#Override
public void adjustString(Set<String> strings) {
this.notifyObservers(); //can this be auto?
}
}
And this works of course, but whoever is implementing ObservableLayer needs to remember to call this.notifyObservers() in the adjustString method. This is not that of a big deal, but I wanted to see if there is a way to completely hide this.
So far, I only have this idea (using template method):
abstract class ObservableLayer implements Layer{
//...methods removed for simplicity
#Override
public void adjustString(Set<String> strings) {
this.doAdjustString(strings);
this.notifyObservers(); //<---- here is auto
}
abstract void doAdjustString(Set<String> strings);
}
class MyLayer extends ObservableLayer{
#Override
public void doAdjustString(Set<String> strings) {
//now notification is in base adjustString
}
}
but here I don't like that method name changed to doAdjustString, and it is not anymore uniform between other layer implementations (layers that directly implement Layer interface).
Is there any easy way to have this functionallity, but to keep public void adjustString(Set<String> strings) signature in MyLayer class?
One way would be to use a Decorator instance that holds an ObservableLayer instance and delegates to it.
final class LayerDecorator implements Layer {
final private ObservableLayer delegate;
public LayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
#Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
delegate.notifyObservers();
}
}
This assumes that calling code is working using references to Layer instead of ObservableLayer.
If calling code has to work using references to ObservableLayer then maybe it is better to refactor ObservableLayer to be an interface having the methods to register listeners, remove them and notify them. This interface also extends the Layer interface.
interface IObservableLayer extends Layer {
void addObserver(NotifiableLayer layer);
void removeObserver(NotifiableLayer layer);
void notifyObservers();
}
The abstract class ObservableLayer changes to implement IObservableLayer instead of Layer directly. This class remains public to support application classes to define variations of observable layers.
Next an internal decorator for observable layers can be defined as shown below.
final class ObservableLayerDecorator implements IObservableLayer {
final private ObservableLayer delegate;
public ObservableLayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
#Override
public void addObserver(NotifiableLayer layer) {
delegate.addObserver(layer);
}
#Override
public void removeObserver(NotifiableLayer layer) {
delegate.removeObserver(layer);
}
#Override
public void notifyObservers() {
delegate.notifyObservers();
}
#Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
this.notifyObservers();
}
}
Please note how the notification is done in this case.
Now instances of IObservableLayer can be created as
IObservableLayer observableLayer = new ObservableLayerDecorator(new MyClass());
Factory methods will be helpful here as they can be defined to handle creation of various application-level observable layer classes so that the instances can be created consistently that return an IObservableLayer which is decorated. That will free up developers from knowing how to use the decorator and allow the decorator to be an internal utility.
Another approach is aspect-oriented programming.
The following example uses AspectJ to intercept any public method execution on a class extending Observable, and invoke notifyObservers() on the same object.
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public class EventAspect {
#AfterReturning("execution(public * Observable.*(..)) && target(observable)")
public void notifyObservers(Observable observable) {
observable.notifyObservers();
}
}
I have 2 classes Workflow1.java and Workflow2.java. At a class Selection.java I want to be able to choose between instantiating one of the 2 classes as a static member however I cannot implement the factory pattern as Workflow1 and Workflow2 cannot be subclasses since their methods are not the same. Although they achieve the same end result they do so by doing entirely different operations. Is there a design pattern for this scenario?
Example: If the classes were WalkHelper.java and DriveHelper.java, the methods you need in each are entirely different but what you are trying to achieve is the same - reach a destination. I haven't created walk() and drive() as methods as WalkHelper.java has existed in our code base and I'm adding DriveHelper.java to it.
It sounds like you can still use a Factory pattern but you may have to use an Adaptor to make them equal... Without knowing more, it's a pretty difficult question to answer.
interface IFactory {
void run();
String getResult();
}
class Workflow1Adapter implements IFactory {
Workflow1 wf1 = new Workflow1();
public void run() {
wf1.doSomething();
}
public String getResult() {
wf1.doAnother();
}
}
class Workflow2Adapter implements IFactory {
Workflow2 wf2 = new Workflow2();
public void run() {
wf2.doThatThing();
}
public String getResult() {
wf2.doReturn();
}
}
class Workflow1 {
public void doSomething() {}
public String doAnother() {}
}
class Workflow2 {
public void doThatThing() {}
public String doReturn() {}
}
A subclass has a relationship that is described as IS-A with it base class, but a base class does not share this kind of relationship with it subclass. I was wandering what kind of relationship an interface have with it implementing class since an object of that class can be passed to interface object and the interface object can only access methods defined it concrete Interface.
public class main {
public static void main(String[]args){
Nigeria ng = new Nigeria(){};
//Interface object can accept Nigerias object which is not posible in Inheritance
Continent continent = ng;
//prints Country is in Africa
continent.Africa();
//continent.language(); will not compile language is not in the interface
//Print Democratic thought this should print Undefined since it is inialied with default.
continent.Goverment();
}
}
interface Continent{
public void Africa();
default void Goverment(){
System.out.println("Undefined");
}
}
class Nigeria implements Continent{
#Override
public void Africa(){
System.out.println("Country is in Africa");
}
public void language(){
System.out.println("Official Language is English");
}
public void Goverment(){
System.out.println("Democratic");
}
}
If you are looking for English-language analogues, an Interface is not an "Is a..." nor "Has a..." relationship, but more an "Is...".
An Interface is not about the class that uses it.
It's about the consumer that asks for it.
If you wanted to see it as anything, you could see it as an adjective.
"He is Responsible".
Well, what does he do?
He finishes tasks; he takes ownership of his mistakes; he makes them right.
Is he a pilot, is he a surgeon, is he a doctor?
Is he a child, a father, a greatGrandfather?
Do you care?
I need a responsible person, to help me do this job.
Does ResponsiblePerson inherit from PoliceOfficer? Does Lawyer inherit from ResponsiblePerson, because I'm sure there can be irresponsible lawyers.
class Lawyer extends Person { }
class ResponsibleLawyer extends Lawyer implements ResponsibleEntity { }
class NeedyPerson extends Person {
public void acceptHelp (ResponsibleEntity somebody) {
try {
somebody.attemptTask( someTask );
} catch (TaskCompletionError err) {
somebody.takeOwnership(err);
somebody.fixMistake(err);
}
}
}
Can corporations be Responsible too?
Perhaps we don't see it too often, but it's theoretically possible:
class LawFirm extends CorporateEntity { }
class BetterLawFirm extends LawFirm implements ResponsibleEntity { }
Can somebody be a responsible corporate body? Well, so long as that corporate body does all of the same things that the responsible person would otherwise do, sure.
In another example, you might have a Switchable interface.
Looking at that name, you could surmise that the thing you're being given has a switch which can be poked.
So what methods might it have?
on( )
off( )
toggle( )
isOn( )
sounds like a useful set to have.
What benefit is there to having an interface like this?
Well, now I know that I can deal with a switch, and its lineage doesn't matter.
If all I want is a class which takes a switch and does something with it, why do I need to create dozens of classes, just to accept my dozens of things with switches?
Or override methods into the dirt to do the same.
class SwitchThrower {
public void throwSwitch (CoffeeMaker coffeeMaker) { coffeeMaker.on(); }
public void throwSwitch (LightSwitch lightSwitch) { lightSwitch.on(); }
public void throwSwitch (GhostTrap ghostTrap) { ghostTrap.on(); }
public void throwSwitch (TheHeat theHeat) { theHeat.on(); }
public void throwSwitch (CarIgnition ignition) { ignition.on(); }
}
...
why not just:
class SwitchThrower {
public void throwSwitch (Switchable switch) { switch.on(); }
}
class LightSwitch implements Switchable {
private boolean currentlyOn;
public LightSwitch (boolean initiallyOn) {
currentlyOn = initiallyOn;
}
public LightSwitch () {
currentlyOn = false;
}
public boolean on () {
currentlyOn = true;
return currentlyOn;
}
public boolean off () {
currentlyOn = false;
return currentlyOn;
}
public boolean toggle (boolean forceOn) {
boolean state;
if (forceOn == true) {
state = on();
} else {
state = off();
}
return state;
}
public boolean toggle () {
boolean state;
if (isOn() == true) {
state = off();
} else {
state = on();
}
return state;
}
public boolean isOn () {
return currentlyOn;
}
}
...et cetera
As you can see, aside from describing a basic feature-set of the implementer, interfaces are not about the class at all, but rather the consumer.
An even more awesome implementation of this, in different languages, is _Traits_.
Traits are typically like Interfaces, but they have default behaviour associated with them.
Looking at my Switchable and my LightSwitch, you could imagine that practically all classes with this switch would have the same methods, with the same method behaviour...
...so why would I rewrite all of those methods over again, if I'm already going through the trouble of defining the signature in the interface?
Why couldn't I just add default behaviour in there, and have it apply to the implementer, unless a method is overridden?
Well, that's what Traits / Mix-Ins allow.
The relationship is only the "contract" that the class is getting to implement the methods the interface is offering.
That is how java can separate WHAT objects can do (Interface) and HOW the inherited class will do it.
I am working on an Android project and i am facing this situation.
I have 2 class :
class A extends B
{
openDoor(){
//impl
}
closeDoor(){
//impl
}
}
class X extends Y{
openDoor(){
//impl
}
closeDoor(){
//impl
}
}
Now if you observe the are two methods common in both the classes openDoor() and closeDoor()
what is the best way to avoid duplicate methods?
My Approach
class ContainingDuplicateMethods{
openDoor(){
//impl
}
closeDoor(){
//impl
}
}
}
Create a object of ContainingDuplicateMethods in both the class and call the methods, which we call it as Strategy Pattern,but is this the best solution? why because in large projects we cannot follow this approach and people say it not GOOD PRACTICE, in that case what approach do i need to follow ?
Please note that class A and X are already extending other classes and also i dont want to use static because - Static members are loaded into memory when the program execution starts and will be in memory until the program is terminated, say my code runs continuously for days or weeks and keeps on creating many number of objects using the static references so there might be a chance that we could run out of memory.
"Favour composition over inheritance" is a useful thing to remember.
Have a Door class with open and close. Include a Door as a member of both A and B.
Voila, job done.
So A.getDoor().close(). B.getDoor().open() etc.
If you need a common interface for both A and B (so you can use either somewhere) then create
interface HasDoor {
Door getDoor();
}
Now A and B can extend any class you like and implement HasDoor. Any class requiring a door can accept a HasDoor (or just directly accept the Door object) and call open, close, etc.
No duplicated code, full flexibility.
If you need your Door to call methods back in A and B then create the Door class as abstract and implement it in A and B as an anonymous inner class. The abstract methods will be called from Door and then you can do whatever processing is needed in A and B when those methods are called.
For example class A becomes:
class A implements HasDoor {
private Door door = new Door() {
#override void notifyDoorChanged(boolean closed) {
// The door is telling us its been opened or closed
}
}
#override
public Door getDoor() {
return door;
}
}
Where door is:
public abstract class Door {
boolean closed;
abstract notifyDoorChanged();
public void close() {
closed = true;
notifyDoorChanged(closed);
}
// etc
}
Note that this is similar to the strategy pattern - but its not quite the same. The Strategy pattern has one master object and then you plug in multiple strategies (i.e. different forms of Door). This has one Door and multiple other objects using the same type of Door, although you could extend it to use the Strategy pattern and have multiple door implementations very easily.
This is the implementation of the answer posted by Tim B.
It is a very flexible approach to go with. It is following the principles of object oriented reuse :
Identify that varies and separate them from what stays the same.
Program to an interface , not an implementation.
Favor object composition over inheritance.
public class Main {
public static void main(String[] args) {
X x = new X();
A a = new A();
x.getDoor().open();
x.getDoor().close();
a.getDoor().open();
a.getDoor().close();
}
}
interface HasDoor {
Door getDoor();
}
interface Door {
public void open();
public void close();
}
class A extends B implements HasDoor {
Door d;
#Override
public Door getDoor() {
Door door = new Door() {
public void open() {
System.out.println("Open A's Door");
}
public void close() {
System.out.println("Close A's Door");
}
};
return door;
}
}
class X extends Y implements HasDoor{
Door d;
#Override
public Door getDoor() {
Door door = new Door() {
public void open() {
System.out.println("Open X's Door");
}
public void close() {
System.out.println("Close X's Door");
}
};
return door;
}
}
class B {}
class Y {}
If you do not want to use HasDoor interface, you can declare constructors inside the class X and class A that initializes the Door instance.
Example ;
class X extends Y {
Door d;
public X() {
d = new Door() {
public void open() {
System.out.println("Open X's Door");
}
public void close() {
System.out.println("Close X's Door");
}
};
}
}
so here your class a and class a has to follow same functions.
that is both classes have same functions.
since the classes already extended another class we can use interface
interface door
{
openDoor(){
}
closeDoor(){
}
}
both class a and x can implement the door interface.
A class can implement any number of interfaces but can extend only one class.
if implementation of class door is same we can do like this
class Door
{
openDoor(){
impl//
}
closeDoor(){
impl//
}
}
class A extends b
{
Door d=new Door();
d.opendoor();
d.closeDorr();
}
Yes, create an abstract class which contains the common code. Have this abstract class implement an interface which contains the necessary methods.
Have both other classes extend the abstract class.
I think you should create an interface with methods openDoor() and closeDoor(). After that inherit classes A and X from this interface and implement methods.
If methods implementation are similar then you can create utility class with static methods.
public interface YourInterface{
public void openDoor();
public void closeDoor();
}
public abstract class YourAbstractClass implements YourInterface{
public abstract void openDoor();
public abstract void closeDoor();
}
public class YourClass extends YourAbstractClass{
#Override
public void openDoor();
public void closeDoor();
}
public class YourSubClass extends YourClass{
//you can just call super methods here
super.openDoor();
super.closeDoor();
}
I am currently working on a project where I am attempting to hide as much detail about a hierarchy I have created as possible. I want to do this to minimize the amount of information the user needs to know about objects (and to control what they can do to the state of the object). In addition, I'm using the pattern to limit what kinds of objects the application can make, and limit it to creation from the factory.
The main issue I am having, however, is that there are a few different kinds of interfaces I would like to expose. Each interface is has additional functionality that I don't believe should be shared, and I would like to keep these interfaces separated. Finally, I don't know what new interfaces may come in the future, but I'd like to try and be ready for them.
Weapon:
public interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
Firearm:
public interface Firearm extends Weapon {
void reload(Number rounds);
}
My question is what would be the best way to have the factory produce objects with different interfaces? Here's what I am thinking "the best would be":
The most clear to the user (it's obvious what they're asking for and what they're getting back)
The best for future expansion (I am uncertain what new interfaces I will be adding to this system).
Here's what I have been thinking so far:
Create properly named methods for each interface
public static Firearm getFirearm(String firearmName) {
...
}
public static Weapon getWeapon(String weaponName) {
...
}
Do the above, but produce the factories in separately named classes
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
public class FirearmFactory {
public static Firearm getFirearm(String firearmName) {
...
}
}
Something completely different
I'm open to suggestions, and changes. This is a flexible project, so I can change as much as I want to (in terms of this portion of the project) to make a better result.
Also - As a side note, I was uncertain if this question was too open-ended or not for SO. If I made a mistake posting here, let me know and I'll move my question elsewhere.
What I can suggest is to make the interfaces as concise as possible and move other unrelated methods elsewhere. you might consider doing this for example:
public interface Weapon extends GameObject {
Number attack();
}
public interface Modifiable extends GameObject {
boolean addWeaponAttribute(WeaponAttribute attribute);
}
public class ActualWeapon implements Weapon, Modifiable {
...
}
Then you can create different factories to generate your concrete objects, as you already mentioned:
public class WeaponFactory {
public static Weapon getWeapon(String weaponName) {
...
}
}
or
public class GenericFactory<T extends GameObject> {
public T createGameObject(Object... properties) {
...
}
}
public class WeaponFactory extends GenericFactory<ActualWeapon> {
public ActualWeapon createGameObject(Object... properties) {
...
}
}
I think you can't add static methods to interfaces. I wouldn't recommend it if you even could.
maybe just use the factory method design pattern like
interface GameObject {}
class WeaponAttribute {}
interface Weapon extends GameObject {
Number attack();
boolean addWeaponAttribute(WeaponAttribute attribute);
}
interface Firearm extends Weapon {
void reload(Number rounds);
}
class WeaponBaseClass implements Weapon {
WeaponBaseClass(WeaponName weaponName) {
this.weaponName=weaponName;
}
#Override public Number attack() {
return null;
}
#Override public boolean addWeaponAttribute(WeaponAttribute attribute) {
return false;
}
public String toString() {
return weaponName.toString();
}
final WeaponName weaponName;
}
class FirearmBaseClass extends WeaponBaseClass implements Firearm {
public FirearmBaseClass(WeaponName weaponName) {
super(weaponName);
}
#Override public void reload(Number rounds) {}
}
enum WeaponName {
knife, sword, colt45, glock19, glock19WithLaser;
}
class WeaponCreator {
Weapon create(WeaponName weaponName) {
switch (weaponName) {
case knife:
case sword:
return new WeaponBaseClass(weaponName);
case colt45:
case glock19:
return new FirearmBaseClass(weaponName);
default:
return new WeaponBaseClass(weaponName);
}
}
}
class FancyWeaponCreator extends WeaponCreator {
Weapon create(WeaponName weaponName) {
Weapon weapon = null;
switch (weaponName) {
case glock19WithLaser:
weapon = super.create(WeaponName.glock19);
// whatever it needs
return weapon;
default:
return new WeaponBaseClass(weaponName);
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println(new WeaponCreator().create(WeaponName.knife));
System.out.println(new WeaponCreator().create(WeaponName.colt45));
System.out.println(new FancyWeaponCreator().create(WeaponName.glock19WithLaser));
}
}
What about a factory of factories? Each factory would implement ifactory. Ifacorty would require a method Instantiate(string type) and return your subclassed weapon instance.
Using generics, you might only need one factory method like:
public <T> T getObject(java.lang.Class<T> responseType, String name)
Then the user would call:
Weapon weapon = factory.getObject(Weapon.class, "my weapon");