【问题标题】:Difference between Bridge and Decorator patternBridge 和 Decorator 模式的区别
【发布时间】:2018-01-20 10:52:39
【问题描述】:

我正在学习软件设计模式,想知道桥接模式和装饰器模式的区别

 interface Iconcept
    {
        void action();
    }
    class concept : Iconcept
    {
        public void action()
        {
            Console.WriteLine("walking ");
        }
    }
    class decoratorA : Iconcept
    {
        Iconcept concept;
        public decoratorA(Iconcept concept)
        {
            this.concept = concept;
        }
        public void action()
        {
            concept.action();
            Console.WriteLine("with his dog");
        }
    }
    class decoratorB : Iconcept
    {
        Iconcept concept;
        public decoratorB(Iconcept concept)
        {
            this.concept = concept;
        }
        public void action()
        {
            concept.action();
            Console.WriteLine("in the rain");
        }
    }
    class client
    {
        static void Main()
        {
            Iconcept concept = new concept();
            concept.action();

            new decoratorA(concept).action();
            new decoratorB(concept).action();


            Console.ReadLine();
        }
    }

装饰器模式

定义:动态地为对象附加额外的职责。装饰器为扩展功能提供了一种灵活的替代子类的方法。

现在,如果我们将此代码用于装饰器模式,我有一个名称概念的实现,并且我正在扩展/装饰该实现,并将新的实现类名称命名为 decoratorA 和 decoratorB

桥接模式

定义:将抽象与其实现分离,以便两者可以独立变化。

我有一个名为 concept 的旧实现,并且在不对旧实现进行任何更改的情况下,我正在实现一个新实现。

这两种模式有什么区别

【问题讨论】:

标签: design-patterns decorator bridge


【解决方案1】:

Bridge 将有两种不同的类型层次结构。一个用于超类抽象,另一个用于实现。超类抽象具有对实现的引用。

另一方面,装饰器结构将在顶部有一个通用类型。装饰对象和装饰对象将共享相同的超类型。装饰器将引用被装饰的对象。

在这两种情况下,客户端都会将实际对象(桥的实现对象和要装饰的对象)传递给桥和装饰器对象。

【讨论】:

    【解决方案2】:

    桥接您可以通过将实现的对象包装成一个不一定共享对象的相同接口的类来将抽象与实现分离。

    装饰器通过将实现的对象包装为继承与实现的对象相同的接口的类来修改现有行为,因此它必须具有相同的行为。

    【讨论】:

      【解决方案3】:

      你应该阅读这页BridgeDecorator,里面有很多关于设计模式的内容,我不喜欢它们的一些代码示例,但意图、问题和结构都得到了很好的解释。

      这两种模式都试图简化复杂的继承类结构,因此它们的意图看起来很相似,但它们试图解决的问题和解决的方式不同。

      Decorator 试图从一个对象中抽象出一些可选的行为,所以你不必多次扩展核心类,典型的例子是 UI 组件。你可以有一个TextView,一个带边框的TextView,一个带边框和阴影的TextView,等等。在那篇文章中有一个与Windows类似的例子。所以解决方案是让抽象Decorator从核心元素的同一个接口扩展,它会有对核心元素的引用。创建文本视图的代码可能是这样的:

      UIElement textview = new BorderTextView(new ShadowTextView(new TextView()));
      

      Bridge 尝试将抽象与其实现分离,并在需要时使两者相互独立。

      Bridge 是“handle/body”成语的同义词。这是一种将实现类封装在接口类内部的设计机制。前者是主体,后者是手柄。用户将句柄视为实际的类,但工作是在主体中完成的。 “句柄/主体类惯用语可用于将复杂抽象分解为更小、更易于管理的类。惯用语可能反映了控制对它的访问的多个类共享单个资源(例如引用计数)。”

      在这种情况下,“handle”引用了“body”,但“body”不知道他的“handle”,不像Decorator,其中行为抽象引用了父抽象,但具体实现(示例中的 textview 核心)不了解装饰器。

      【讨论】:

        【解决方案4】:

        装饰器和桥接模式都使用组合。 恕我直言,区别在于客户端代码使用这些模式的方式。

        桥接模式将实现注入到抽象中。 然后它从抽象中调用方法。

        $implementation = new MyImplementationA;
        $abstraction = new AbstractionParent($implementation);
        $abstraction->doSomething();
        
        $implementation = new MyImplementationB;
        $abstraction = new AbstractionChild($implementation);
        $abstraction->doSomething();
        

        装饰器模式像这样堆叠对象:

        $helloWorldBase = new HelloWorldBase();
        $helloWorldDecoEN = new HelloWorlDecoratorEN($helloWorldBase);
        $helloWorldDecoNL = new HelloWorlDecoratorNL($helloWorldDecoEN);
        $helloWorldDecoPL = new HelloWorlDecoratorPL($helloWorldDecoNL);
        $decorator = new HelloWorldBaseDecorator($helloWorldDecoPL);
        echo $decorator->sayHello();
        

        【讨论】:

          猜你喜欢
          • 2012-01-15
          • 2014-04-23
          • 1970-01-01
          • 2019-05-15
          • 1970-01-01
          • 2020-08-23
          • 2013-08-09
          • 2011-01-06
          • 2013-01-18
          相关资源
          最近更新 更多