Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a decorator or a strategy pattern, or neither of the two?

I have the following interface.

PowerSwitch.java

public interface PowerSwitch {
    public boolean powerOn();
    public boolean powerOff();
    public boolean isPowerOn();
}

The above interface should consist of the minimum set of methods which any other functionality can be derived from, to make it as easy as possible to add additional PowerSwitch implementations.

I would like to add functionality to the PowerSwitch interface at run-time (what decorators do), by creating a class which holds a composition of a PowerSwitch instance and adds new methods, like the two toggleOnOff() methods below. That way i only need to implement the two toggle methods once and it will apply to all PowerSwitch implementations.

Is this considered as a good/bad practice? If bad, any other recommendations?

It doesn't really comply to the decorator-pattern as it adds extra methods. Is it a strategy pattern, or a composition pattern? Or does it have another pattern name? Is there such thing as an "interface decorator"?

PowerSwitchDecorator.java

public class PowerSwitchDecorator {
    private PowerSwitch ps;

    public PowerSwitchDecorator(PowerSwitch ps) {
        this.ps = ps;
    }

    public void toggleOnOff(int millis) throws InterruptedException{
        powerOn();
        Thread.sleep(millis);
        powerOff();
    }

    public void toggleOnOff(){
    powerOn();
    powerOff();
    }

    public boolean powerOn() {
        return ps.powerOn();
    }

    public boolean powerOff() {
        return ps.powerOff();
    }

    public boolean isPowerOn() {
        return ps.isPowerOn();
    }
}
like image 799
etxalpo Avatar asked Jan 24 '12 08:01

etxalpo


People also ask

What is the difference between Decorator and Strategy pattern?

The strategy pattern allows you to change the implementation of something used at runtime. The decorator pattern allows you augment (or add to) existing functionality with additional functionality at run time.

What type of pattern is decorator pattern?

Decorator design pattern is one of the structural design pattern (such as Adapter Pattern, Bridge Pattern, Composite Pattern) and uses abstract classes or interface with composition to implement.

Is Decorator a pattern?

Decorator patterns allow a user to add new functionality to an existing object without altering its structure. So, there is no change to the original class. The decorator design pattern is a structural pattern, which provides a wrapper to the existing class.

What is the decorator pattern also known as?

A Decorator Pattern says that just "attach a flexible additional responsibilities to an object dynamically". In other words, The Decorator Pattern uses composition instead of inheritance to extend the functionality of an object at runtime. The Decorator Pattern is also known as Wrapper.


2 Answers

As it is, any code that wants to use the toggleOnOff(int) or toggleOnOff() methods is going to need an instance of PowerSwitchDecorator, not PowerSwitch. This kind of defeats the purpose of a decorator which should be transparent to the client.

If you want all implementations to have these methods, you should include them in the PowerSwitch interface.

Then, as @Ani suggests, you could modify the above PowerSwitchDecorator to extend PowerSwitch so you can do this:

PowerSwitch switch = new PowerSwitchDecorator(new ConcretePowerSwitch());
switch.toggleOnOff();

Now you have a variable of type PowerSwitch with the PowerSwitchDecorator's capabilities.

EDIT: Note that you should only use an established pattern if it meets your needs. You can use the approach you have shown if it works for you. No need to shoe-horn it into a specific pattern.

What type of object do you want to pass around though? Do you want methods like this in your API:

void connect(PowerSwitch powerSwitch, Appliance appliance);

Or methods like this:

void connect(PowerSwitchDecorator powerSwitch, Appliance appliance);

(sorry, they're not very good examples)

If you want the former, then everyone is going to have to manually 'decorate' their PowerSwitch just to get a couple of convenience methods. It may be convenient for you now but I think that it will be inconvenient for users of your code and they will probably not bother with it. If you want the latter, you have to use the type PowerSwitchDecorator in your method signatures, which tends to mean that you always deal with PowerSwitchDecorators and not raw PowerSwitches.

like image 176
Gyan aka Gary Buyn Avatar answered Nov 15 '22 16:11

Gyan aka Gary Buyn


That's a good practice in the case you need to enhance your PowerSwitch instance at runtime. I recommend you to implement The PowerSwitch interface in the decorator. The other name of decorator pattern is proxy pattern.

You can define the extended methods in another interface which extends your PowerSwitch interface. That will avoid having a dependency on the decorator when these extended methods are needed to be called.

Extending a class is a good practice when you need to enhance or redefine a behavior at compilation.

like image 28
vanadium Avatar answered Nov 15 '22 16:11

vanadium