Il modello Decorator può essere utilizzato senza un'interfaccia?

1

La maggior parte delle risorse che ho visto a proposito del pattern Decorator sono le seguenti:

interface Tea
{
    public double cost();
}
class BasicTea implements Tea
{
    public double cost() { return 1.99; }
}
abstract class TeaDecorator implements Tea
{
    private Tea base;
    public TeaDecorator(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost(); }
}
class TeaWithMilk extends TeaDecorator
{
    public TeaWithMilk(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.30; }
}
class TeaWithSugar extends TeaDecorator
{
    public TeaWithSugar(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.10; }
}

decoratedTea = new TeaWithSugar(new TeaWithMilk(new BasicTea()));

Tuttavia, ho notato che il seguente approccio funziona anche - decoratedTea.cost() restituisce lo stesso valore di cui sopra.

class Tea
{
    public double cost() { return 1.99; }
}
abstract class TeaDecorator extends Tea
{
    private Tea base;
    public TeaDecorator(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost(); }
}
class TeaWithMilk extends TeaDecorator
{
    public TeaWithMilk(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.30; }
}
class TeaWithSugar extends TeaDecorator
{
    public TeaWithSugar(Tea tea) { this.base = tea; }
    public double cost() { return this.base.cost() + 0.10; }
}

decoratedTea = new TeaWithSugar(new TeaWithMilk(new Tea()));

C'è qualche problema con questo metodo? Se altrimenti non avrei un'interfaccia per Tea, è necessario aggiungerne uno solo per implementare il pattern Decorator?

    
posta DisgruntledGoat 04.01.2018 - 19:50
fonte

2 risposte

5

Puoi certamente implementare il pattern Decorator senza la parola chiave lingua interface , perché puoi scrivere decoratori in linguaggi che non si distinguono a livello di parola chiave tra una classe senza metodi implementati, uno con alcuni metodi non implementati e uno con solo metodi implementati. ( interface di Java e C #, abstract class e class ). C ++ usa class per tutti e tre.

Ciò che non puoi fare è parlare del pattern Decorator senza il concetto di Interface di class , perché la essence di Decorator fornisce qualcosa di la stessa Interfaccia e un'implementazione che delega (parte) a un'implementazione esistente di quella Interfaccia

    
risposta data 05.01.2018 - 00:53
fonte
0

Una definizione del pattern Decorator (la mia enfasi) è:

[...] decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. https://en.m.wikipedia.org/wiki/Decorator_pattern

Il tuo secondo esempio utilizza l'ereditarietà; quindi ogni istanza di TeaWithMilk avrebbe lo stesso comportamento.

È certamente possibile implementare il pattern Decorator senza interfacce.
Ad esempio una versione JavaScript:

class Tea
{
    cost() { return 1.99; }
}

class WithMilk
{
    constructor(tea)
    {
        this.tea = tea;
    }

    cost()
    {
        return this.tea.cost() + 0.50;
    }
}
    
risposta data 04.01.2018 - 20:10
fonte

Leggi altre domande sui tag