Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorator pattern - access value in wrapped object from decorator

I have a question about the decorator pattern

Lets say I have this code

interface IThingy 
{
    void Execute(); 
}

internal class Thing : IThingy
{
    public readonly string CanSeeThisValue;

    public Thing(string canSeeThisValue)
    {
        CanSeeThisValue = canSeeThisValue;
    }

    public void Execute()
    {
        throw new System.NotImplementedException();
    } 
}

class Aaa : IThingy 
{
    private readonly IThingy thingy;

    public Aaa(IThingy thingy)
    {
        this.thingy = thingy;
    }

    public void Execute()
    {
        throw new System.NotImplementedException();
    } 
}


class Bbb : IThingy {
    private readonly IThingy thingy;

    public Bbb(IThingy thingy)
    {
        this.thingy = thingy;
    }

    public void Execute()
    {
        throw new System.NotImplementedException();
    } 
}

class Runit {
    void Main()
    {
        Aaa a = new Aaa(new Bbb(new Thing("Can this be accessed in decorators?")));
    } 
}

We have a class called thing that is wrapped by two decorators Aaa and Bbb

How can I best access the string value "CanSeeThisValue" (which is in Thing) from Aaa or Bbb

I tried to make a base class for them all, but of course while they share the same base, they don't share the same instance of the base

Do I need to pass the value into each constructor instead?

like image 946
ChrisCa Avatar asked Nov 05 '22 00:11

ChrisCa


1 Answers

Decorators add functionality to the public interface of the items they are wrapping. If you want your decorator to access members of Thing, that are not part of IThingy, then you should consider whether the decorator should wrap Thing instead of IThingy.

Or, if all IThingy should have a CanSeeThisValue property, make that property part of the IThingy interface as well by adding (and implementing) it as a property.

interface IThingy 
{
    string CanSeeThisValue { get; }

    void Execute(); 
}

Which would make Thing look like:

internal class Thing : IThingy
{
    public string CanSeeThisValue { get; private set; }

    public Thing(string canSeeThisValue)
    {
        CanSeeThisValue = canSeeThisValue;
    }

    ...

} 
like image 173
James Michael Hare Avatar answered Nov 09 '22 06:11

James Michael Hare