Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorator pattern for classes with many properties

I have this simple class:

public class DataBag
{
    public string UserControl { get; set; }
    public string LoadMethod { get; set; }
    public dynamic Params { get; set; }
    public int Height { get; set; }

    public DataBag(string Control, 
        object vars, string lm)
    {
        UserControl = Control;
        LoadMethod = lm;
        Params = vars;
        Height = 0;
    }
}

I then would like to create a decorator for it that would add a bunch of it's own properties. Question is what's the most concise and elegant way to provide access to decorated properties?

So far I have two options: either I provide a get-set pair for every of four decorated properties in decorator (which seems tedious and mouthful and basically it's what I want to avoid) or I inherit DataBag from DynamicObject and then somehow manage to get decorated properties using TryGetMember method (which is dynamic and does not seem to be the right way to do things in C#).

Any advice?

like image 739
src091 Avatar asked Dec 20 '12 21:12

src091


2 Answers

When implementing decorator I usually do following. First - extract interface of decorated object and make decorated object implement that interface:

public interface IDataBag
{
    string UserControl { get; set; }
    string LoadMethod { get; set; }
    dynamic Params { get; set; }
    int Height { get; set; }
}

Next - create a decorator, which delegates all calls to decorated object (all decorators will inherit from this decorator):

public class DataBagDecorator : IDataBag
{
    private IDataBag _dataBag;

    public DataBagDecorator(IDataBag dataBag)
    {
        _dataBag = dataBag;
    }

    public virtual string UserControl
    {
        get { return _dataBag.UserControl; }
        set { _dataBag.UserControl = value; }
    }

    // other members
}

Last - creating decorators:

public class FooDataBag : DataBagDecorator
{
    public FooDataBag(IDataBag dataBag) 
        : base(dataBag) { }

    public override string UserControl
    {
        // added behavior
        get { return "Foo" + base.UserControl; }
        set { base.UserControl = value; }
    }

    // you don't need to override other members
}

Usage:

IDataBag dataBag = new FooDataBag(new DataBag());
like image 165
Sergey Berezovskiy Avatar answered Oct 06 '22 01:10

Sergey Berezovskiy


This is the simplest way to decorate:

public class PrettyBag : DataBag
{
    public int Decoration1 { get; set; }
    public int Decoration2 { get; set; }
}

If you want to create a facade and hide some of the DataBag properties instead of just adding properties then you can make the members of DataBag protected.

With interfaces you could do:

    public interface IDataBag
    {
       ...
    }
    public class DataBag : IDataBag
    {
       ...
    }
    public interface IPrettyBag : IDataBag
    {
        int Decoration1 { get; set; }
        int Decoration2 { get; set; }
    }
    public class BigBag : IPrettyBag
    {
        public int Decoration1 { get; set; }
        public int Decoration2 { get; set; }
    }
    public interface SmallBag : IPrettyBag
    {
        public int Decoration1 { get; set; }
        public int Decoration2 { get; set; }
    }
like image 35
Nick Bray Avatar answered Oct 06 '22 00:10

Nick Bray