【问题标题】:Is the decorator pattern the correct pattern to be used on this situation装饰器模式是在这种情况下使用的正确模式吗
【发布时间】:2018-08-04 19:53:43
【问题描述】:

我想问一下装饰器模式是否适合我的需求,是另一种让我的软件设计更好的方法吗?

以前我有一个始终开启的设备。在下面的代码中,这就是 Device 类。现在,为了节省一些电池寿命,我需要将其关闭然后再次打开。我创建了一个 DeviceWithOnOffDecorator 类。我使用了装饰器模式,我认为这有助于避免对 Device 类进行修改。但是每次操作都有On和Off,感觉代码不符合DRY原则。

namespace Decorator
{
    interface IDevice
    {
        byte[] GetData();
        void SendData();
    }


    class Device : IDevice
    {
        public byte[] GetData() {return new byte[] {1,2,3 }; }
        public void SendData() {Console.WriteLine("Sending Data"); }
    }


    // new requirement, the device needs to be turned on and turned off
    // after each operation to save some Battery Power
    class DeviceWithOnOffDecorator:IDevice
    {
        IDevice mIdevice;

        public DeviceWithOnOffDecorator(IDevice d)
        {
            this.mIdevice = d;
            Off();
        }

        void Off() { Console.WriteLine("Off");}
        void On() { Console.WriteLine("On"); }

        public byte[] GetData()
        {
            On();
            var b = mIdevice.GetData();
            Off();
            return b;
        }


        public void SendData()
        {
            On();
            mIdevice.SendData();
            Off();
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Device device = new Device();
            DeviceWithOnOffDecorator devicewithOnOff = new DeviceWithOnOffDecorator(device);
            IDevice iDevice = devicewithOnOff;

            var data = iDevice.GetData();
            iDevice.SendData();
        }
    }
}

在这个例子中:我只有 GetDataSendData 两个操作,但在实际的软件中涉及很多操作,我需要将每个操作都包含在内开和关,

void AnotherOperation1()
{
On();
// do all stuffs here
Off();
}

byte AnotherOperation2()
{
On();
byte b;
// do all stuffs here
Off();
return b;
}

我觉得每个函数都用 On 和 Off 括起来是重复的,有没有办法改进呢?

编辑:另外,原始代码是用 C++ 编写的。我只是在这里用 C# 写的,以便能够更清楚地显示问题。

【问题讨论】:

  • 嗯。您正在寻找的是一种在您对On()Off() 的调用之间自动委托Device 类方法的方法。不幸的是,Java 不允许您动态添加方法,因此您无法“即时”构建修饰版本。如果您想深入了解虚拟机的内部,可以使用自定义类加载器来完成......但这不是一个实际的解决方案。相反,您可能想查看面向方面的编程。一个简短的搜索显示 Android 对 AspectJ 有一些支持。从概念上讲,方面让您“挂钩”类的方法。
  • 您好,感谢您的评论。但是,我忘了提一下,我是在 C++ 中实现的。在这种情况下,我只是使用了 C#,以便能够以更清晰的方式显示问题。
  • 好吧,总是有 AspectC++,或者你可以解析 Device 类头并为修饰的子类生成代码(将调用从 Device 委托给 On()Off() 之间的版本),或者您可以硬着头皮为Device 上的每个方法添加一个通用的“钩子”接口。然后您的 On/Off 子类可以安装用于打开和关闭电源的挂钩。至少 Device 中的钩子是通用的(不耦合到开/关功能)

标签: oop design-patterns decorator


【解决方案1】:

Decorator 不适合此目的,因为您没有动态添加责任。对我来说,您需要做的是拦截请求并在实际调用之前和之后执行on()off() 方法。为此,编写一个 Proxy 包装底层实例并在那里进行拦截,同时保持原始类型不变。

【讨论】:

    猜你喜欢
    • 2011-09-08
    • 1970-01-01
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多