正确地将请求委托给内部对象

时间:2013-07-12 15:03:12

标签: c# visual-studio-2010

我正在试图找出我是否以正确的方式看待遏制/委托。在此示例中,我有CarRadio类型。我有一个函数,它接受一个字符串并更改Radio对象的IsOn属性的值。我想知道哪种方法(或两种方法)都没有足够的方法来解决这个问题。

(为简单起见,请忽略将输入字符串验证到TurnOn方法中)

 public int Year { get; set; }
        public string Model { get; set; }
        protected Radio radio = new Radio();
        public Radio MyRadio
        {
            get { return radio; }
            set { radio = value; }
        }

        public class Radio
        {
            public string ModelNumber { get; set; }
            public bool IsOn { get; set; }
            public void TurnOn(string turnOn)
            {
                if (turnOn == "yes")
                {
                    if (IsOn)
                        Console.WriteLine("The radio is already on");
                    else
                    {
                        IsOn = true;
                        Console.WriteLine("You turned on the radio");
                    }
                }
                else
                {
                    if (IsOn)
                    {
                        IsOn = false;
                        Console.WriteLine("You turned off the radio");
                    }
                }

            }

        }

我在我的Main方法中对此进行了测试,输出位于注释

中的每一行旁边
  Car c = new Car();
    Console.WriteLine(c.MyRadio.IsOn); //false
    c.MyRadio.TurnOn("yes"); //you turned on the radio
    Console.WriteLine(c.MyRadio.IsOn);//true
    c.MyRadio.TurnOn("yes"); //the radio is already on
    c.MyRadio.TurnOn("no"); //you turned off the radio
    Console.WriteLine(c.MyRadio.IsOn); //false

我想到的另一种方法是将以下函数添加到Car类

public void CarChangesState(string s)
        {
            MyRadio.TurnOn(s);
        }

我使用以下代码测试了它,一切都按预期工作

Car c2 = new Car();
            Console.WriteLine(c2.MyRadio.IsOn);//false
            c2.CarChangesState("yes"); //you turned on the radio
            Console.WriteLine(c2.MyRadio.IsOn);//true 
            c2.CarChangesState("yes");//the radio is already on
            c2.CarChangesState("no");//you turned off the radio
            Console.WriteLine(c2.MyRadio.IsOn); //false

一个例子比另一个好吗?从我对Pro C# and the .NET Framework的阅读中我感觉第一次迭代并不是真正的委托,但我想知道一种方法是否比另一种方法具有更少的缺点。

2 个答案:

答案 0 :(得分:1)

你的第二种方法是授权。第一种方法不是。

代表团意味着您要求某个对象(例如Car)打开收音机。 Car不知道如何打开收音机,但他知道是谁。所以他将消息传递给Radio

简单地公开无线电对象的第一种方法不是授权,因为Car从未收到打开无线电的请求,因此从不委托打开无线电的请求。

此外,许多纯粹主义者会批评你的第一种方法,因为它违反了Law of Demeter,但在实践中,我发现自己为了方便/可读性而偶尔这样做。 (也许我只是一个糟糕的开发者?)

答案 1 :(得分:0)

你可能指的是这样的东西:

    class Car
    {
        // Car 'has-a' Radio.
        protected Radio radio = new Radio();
        public Radio MyRadio
        {
            get { return radio; }
            set { radio = value; }
        }
        public void TurnOnRadio(bool onOff)
        {
            // Delegate call to inner object.
            MyRadio.TurnOn(onOff);
        }
    }

    public class Radio
    {
        public string ModelNumber { get; set; }
        public bool IsOn { get; set; }

        public void TurnOn(bool turnOn)
        {
            if (turnOn)
            {
                if (IsOn)
                    Console.WriteLine("The radio is already on");
                else
                {
                    IsOn = true;
                    Console.WriteLine("You turned on the radio");
                }
            }
            else
            {
                if (IsOn)
                {
                    IsOn = false;
                    Console.WriteLine("You turned off the radio");
                }
            }

        }

    }

Radion是一辆汽车吗?不是,然后汽车有一个收音机,你直接打电话打开或关闭收音机。

Car c = new Car();
c.TurnOnRadio(true);