是否有用于创建可以访问受保护成员的工作类的标准模式?

时间:2012-10-29 17:54:44

标签: c# inheritance design-patterns

我只是使用一个部分类做了一些古怪的事情,我想知道是否已经建立的模式可能使用一种不那么混乱的方法完成了同样的事情。

问题:

  • 我有一个带有受保护成员的基类和为派生类设计的虚方法,以便在调用它们时起作用。

  • 我想将这项工作委托给工人名单。

  • 但是我需要工人才能访问受保护的成员。

我可能过于复杂的解决方案:

注意:我意识到这取决于班级的偏见 - 我没关系,但如果有一个不需要它的解决方案会很酷......

void Main()
{
    ABase aBase = new ADerived();
    aBase.DoWork();
}

public partial class ABase
{
    protected int state1 = 1;
    protected int state2 = 2;
    List<ABase> workers;

    public ABase()
    {
        workers = new List<ABase>();
        CreateWorkers(workers);
    }

    protected virtual void CreateWorkers(List<ABase> workers)
    {
    }

    public ABase(ABase aBase)
    {
        this.Target = aBase;
    }

    public virtual void DoWork()
    {
        foreach (var worker in this.workers)
        {
            worker.DoWork();
        }
    }

    protected ABase Target { get; private set; }
}

public partial class ABase
{
    public class Worker1 : ABase
    {
        public Worker1(ABase aBase) : base(aBase) { }

        public override void DoWork()
        {
            Console.WriteLine (Target.state1);
        }
    }

    public class Worker2 : ABase
    {
        public Worker2(ABase aBase) : base(aBase) { }

        public override void DoWork()
        {
            Console.WriteLine (Target.state2);
        }
    }
}

public class ADerived : ABase
{
    protected override void CreateWorkers(List<ABase> workers) 
    {
        workers.Add(new Worker1(this));
        workers.Add(new Worker2(this));
    }
}

输出:

1
2

1 个答案:

答案 0 :(得分:0)

我会更改设计,以便工作人员根本不访问实例字段。我会DoWork使用他们需要的信息获取参数,并让基类将状态传递给DoWork方法。

public class MyState //TODO give better name
{
    public int State1 { get; set; }
    public int State2 { get; set; }
}

public class ABase
{
    public MyState state = new MyState()
    {
        State1 = 1,
        State2 = 2
    };

    List<Action<MyState>> workers = new List<Action<MyState>>();

    public ABase()
    {
        CreateWorkers();
    }

    public void DoWork()
    {
        foreach (var action in workers)
        {
            action(state);
        }
    }

    private void CreateWorkers()
    {
        workers.Add(new Worker1().DoWork);
        workers.Add(Worker2.Process);
    }
}

public class Worker1
{
    public void DoWork(MyState state)
    {
        Console.WriteLine(state.State1);
    }
}

public class Worker2
{
    public static void Process(MyState state)
    {
        Console.WriteLine(state.State2);
    }
}