名称

Adapter

结构

意图

将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

适用性

  • 你想使用一个已经存在的类,而它的接口不符合你的需求。
  • 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • (仅适用于对象A d a p t e r )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

Code Example

namespace Adapter_DesignPattern
{
    using System;
 
          class FrameworkXTarget 
          {
                    virtual public void SomeRequest(int x)
                    {
                               // normal implementation of SomeRequest goes here                                          
                    }
          }
 
          class FrameworkYAdaptee
          {
                    public void QuiteADifferentRequest(string str) 
                    {
                               Console.WriteLine("QuiteADifferentRequest = {0}", str);
                    }                   
          }
 
          class OurAdapter : FrameworkXTarget
          {
                    private FrameworkYAdaptee adaptee = new FrameworkYAdaptee();
                    override public void SomeRequest(int a)
                    {
                               string b;
                               b = a.ToString();
                               adaptee.QuiteADifferentRequest(b);
                    }                   
          }
 
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        void GenericClientCode(FrameworkXTarget x)
                    {
                               // We assume this function contains client-side code that only 
                               // knows about FrameworkXTarget.
                               x.SomeRequest(4);
                               // other calls to FrameworkX go here
                               // ...
                    }
                    
                    public static int Main(string[] args)
        {
                               Client c = new Client();
            FrameworkXTarget x = new OurAdapter();
                               c.GenericClientCode(x);        
            return 0;
        }
    }
}

名称

Bridge

结构

意图

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

适用性

  • 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时B r i d g e 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  • (C + +)你想对客户完全隐藏抽象的实现部分。在C + +中,类的表示在类接口中是可见的。
  • 有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。R u m b a u g h 称这种类层次结构为“嵌套的普化”(nested generalizations )。
  • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是C o p l i e n 的S t r i n g 类[ C o p 9 2 ],在这个类中多个对象可以共享同一个字符串表示(S t r i n g R e p )。

Code Example

namespace Bridge_DesignPattern
{
    using System;
 
          class Abstraction 
          {
                    protected Implementation impToUse;
 
                    public void SetImplementation(Implementation i)
                    {
                               impToUse = i;
                    }
 
                    virtual public void DumpString(string str)
                    {
                               impToUse.DoStringOp(str);                                       
                    }
          }
 
          class DerivedAbstraction_One : Abstraction 
          {
                    override public void DumpString(string str)
                    {
                               str += ".com";
                               impToUse.DoStringOp(str);                          
                    }                   
          }
 
          class Implementation 
          {
                    public virtual void DoStringOp(string str)
                    {
                               Console.WriteLine("Standard implementation - print string as is");
                               Console.WriteLine("string = {0}", str);
                    }                   
          }
 
          class DerivedImplementation_One : Implementation 
          {
                    override public void DoStringOp(string str)
                    {
                               Console.WriteLine("DerivedImplementation_One - don't print string");
                    }         
          }
 
          class DerivedImplementation_Two : Implementation 
          {
                    override public void DoStringOp(string str)
                    {
                               Console.WriteLine("DerivedImplementation_Two - print string twice");
                               Console.WriteLine("string = {0}", str);
                               Console.WriteLine("string = {0}", str);
                    }         
          }
          
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        Abstraction SetupMyParticularAbstraction() 
                    {
                               // we localize to this method the decision which abstraction and
                               // which implementation to use. These need to be decided 
                               // somewhere and we do it here. All teh rest of the client 
                               // code can work against the abstraction object. 
                               Abstraction a = new DerivedAbstraction_One();
                               a.SetImplementation(new DerivedImplementation_Two());
                               return a;
                    }
 
                    public static int Main(string[] args)
        {           
            Client c = new Client();
                               Abstraction a = c.SetupMyParticularAbstraction();
                    
                               // From here on client code thinks it is talking to the 
                               // abstraction, and will not need to be changed as 
                               // derived abstractions are changed. 
 
                               // more client code using the abstraction goes here 
                               // . . . 
                               a.DumpString("Clipcode");
 
                               return 0;
        }
    }
}

名称

Composite

结构

意图

将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。

适用性

  • 你想表示对象的部分-整体层次结构。
  • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

Code Example

namespace FactoryMethod_DesignPattern
{
    using System;
          using System.Collections;
 
          abstract class Component 
          {
                    protected string strName;
 
                    public Component(string name)
                    {
                               strName = name;
                    }
 
                    abstract public void Add(Component c);
          
                    public abstract void DumpContents();
                    
                    // other operations for delete, get, etc.
          }
 
          class Composite : Component
          {
                    private ArrayList ComponentList = new ArrayList();
                    
                    public Composite(string s) : base(s) {}
 
                    override public void Add(Component c)
                    {
                               ComponentList.Add(c);
                    }
 
                    public override void DumpContents()
                    {
                               // First dump the name of this composite node
                               Console.WriteLine("Node: {0}", strName);
 
                               // Then loop through children, and get then to dump their contents
                               foreach (Component c in ComponentList)
                               {
                                         c.DumpContents();
                               }
                    }
          }
 
          class Leaf : Component
          {
                    public Leaf(string s) : base(s) {}
 
                    override public void Add(Component c)
                    {
                               Console.WriteLine("Cannot add to a leaf");
                    }
 
                    public override void DumpContents()
                    {
                               Console.WriteLine("Node: {0}", strName);
                    }
          }
 
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
                    Component SetupTree()
                    {
                               // here we have to create a tree structure, 
                               // consisting of composites and leafs.  
                               Composite root = new Composite("root-composite");
                               Composite parentcomposite;
                               Composite composite;
                               Leaf leaf;
 
                               parentcomposite = root;
                               composite = new Composite("first level - first sibling - composite");
                               parentcomposite.Add(composite);
                               leaf = new Leaf("first level - second sibling - leaf");
                               parentcomposite.Add(leaf);
                               parentcomposite = composite; 
                               composite = new Composite("second level - first sibling - composite");
                               parentcomposite.Add(composite);
                               composite = new Composite("second level - second sibling - composite");
                               parentcomposite.Add(composite);
 
                               // we will leaf the second level - first sibling empty, and start 
                               // populating the second level - second sibling 
                               parentcomposite = composite; 
                               leaf = new Leaf("third level - first sibling - leaf");
                               parentcomposite.Add(leaf);
                               
                               leaf = new Leaf("third level - second sibling - leaf");
                               parentcomposite.Add(leaf);
                               composite = new Composite("third level - third sibling - composite");
                               parentcomposite.Add(composite);
 
                               return root;
                    }
 
        public static int Main(string[] args)
        {   
                    Component component;
                               Client c = new Client();
                               component = c.SetupTree();
 
                               component.DumpContents();
            return 0;
        }
    }
}

名称

Decorator

结构

意图

动态地给一个对象添加一些额外的职责。就增加功能来说,D e c o r a t o r 模式相比生成子类更为灵活。

适用性

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤消的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

Code Example

namespace Decorator_DesignPattern
{
    using System;
 
          abstract class Component
          {
                    public abstract void Draw();             
          }
 
          class ConcreteComponent : Component
          {
                    private string strName;
                    public ConcreteComponent(string s)
                    {
                               strName = s;                             
                    }
 
                    public override void Draw()
                    {
                               Console.WriteLine("ConcreteComponent - {0}", strName);                           
                    }                   
          }
 
          abstract class Decorator : Component
          {
                    protected Component ActualComponent;
 
                    public void SetComponent(Component c)
                    {
                               ActualComponent = c;
                    }
                    public override void Draw()
                    {
                              if (ActualComponent != null)
                                         ActualComponent.Draw();                  
                    }
          }
 
          class ConcreteDecorator : Decorator 
          {
                    private string strDecoratorName;
                    public ConcreteDecorator (string str)
                    {
                               // how decoration occurs is localized inside this decorator
                               // For this demo, we simply print a decorator name
                               strDecoratorName = str; 
                    }
                    public override void Draw()
                    {
                               CustomDecoration();
                               base.Draw();
                    }
                    void CustomDecoration()
                    {
                               Console.WriteLine("In ConcreteDecorator: decoration goes here");
                               Console.WriteLine("{0}", strDecoratorName);
                    }
          }
 
          
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        Component Setup() 
                    {
                               ConcreteComponent c = new ConcreteComponent("This is the real component");
 
                               ConcreteDecorator d = new ConcreteDecorator("This is a decorator for the component");
 
                               d.SetComponent(c);
 
                               return d;
                    }
                    
                    public static int Main(string[] args)
                    {
                               Client client = new Client();
                               Component c = client.Setup();    
 
                               // The code below will work equally well with the real component, 
                               // or a decorator for the component
 
                               c.Draw();
                               
            return 0;
        }
    }
}

名称

Facade

结构

意图

为子系统中的一组接口提供一个一致的界面,F a c a d e 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

适用性

  • 当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。F a c a d e 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过f a c a d e 层。
  • 客户程序与抽象类的实现部分之间存在着很大的依赖性。引入f a c a d e 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
  • 当你需要构建一个层次结构的子系统时,使用f a c a d e 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过f a c a d e 进行通讯,从而简化了它们之间的依赖关系。

Code Example

namespace Facade_DesignPattern
{
          using System;
 
          class SubSystem_class1 
          {
                    public void OperationX() 
                    {
                               Console.WriteLine("SubSystem_class1.OperationX called");
                    }
          }
 
          class SubSystem_class2
          {
                    public void OperationY()
                    {
                               Console.WriteLine("SubSystem_class2.OperationY called");
                    }
          }
 
          class SubSystem_class3 
          {
                    public void OperationZ()
                    {                              
                               Console.WriteLine("SubSystem_class3.OperationZ called");
                    }         
          }
 
          class Facade 
          {
                    private SubSystem_class1 c1 = new SubSystem_class1();
                    private SubSystem_class2 c2 = new SubSystem_class2();
                    private SubSystem_class3 c3 = new SubSystem_class3();
 
                    public void OperationWrapper()
                    {
                               Console.WriteLine("The Facade OperationWrapper carries out complex decision-making");
                               Console.WriteLine("which in turn results in calls to the subsystem classes");
                               c1.OperationX();
                               if (1==1 /*some really complex decision*/)
                               {
                                         c2.OperationY();
                               }
                               // lots of complex code here . . .
                               c3.OperationZ();
                    }
                    
          }
 
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
          public static int Main(string[] args)
                    {
                               Facade facade = new Facade();
                               Console.WriteLine("Client calls the Facade OperationWrapper");
                               facade.OperationWrapper();      
            return 0;
        }
    }
}

名称

Flyweight

结构

意图

运用共享技术有效地支持大量细粒度的对象。

适用性

  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量的对象,造成很大的存储开销。
  • 对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

Code Example

namespace Flyweight_DesignPattern
{
    using System;
          using System.Collections;
 
          class FlyweightFactory 
          {
                    private ArrayList pool = new ArrayList();
 
                    // the flyweightfactory can crete all entries in the pool at startup 
                    // (if the pool is small, and it is likely all will be used), or as 
                    // needed, if the pool si large and it is likely some will never be used
                    public FlyweightFactory()
                    {
                               pool.Add(new ConcreteEvenFlyweight());             
                               pool.Add(new ConcreteUnevenFlyweight());                     
                    }
 
                    public Flyweight GetFlyweight(int key)
                    {
                               // here we would determine if the flyweight identified by key 
                               // exists, and if so return it. If not, we would create it. 
                               // As in this demo we have implementation all the possible 
                               // flyweights we wish to use, we retrun the suitable one. 
                               int i = key % 2;
                              return((Flyweight)pool[i]); 
                    }
          }
 
          abstract class Flyweight 
          {
                    abstract public void DoOperation(int extrinsicState);                  
          }
 
          class UnsharedConcreteFlyweight : Flyweight
          {
                    override public void DoOperation(int extrinsicState)
                    {
                               
                    }
          }
 
          class ConcreteEvenFlyweight : Flyweight
          {
                    override public void DoOperation(int extrinsicState)
                    {
                               Console.WriteLine("In ConcreteEvenFlyweight.DoOperation: {0}", extrinsicState);                                                       
                    }
          }
 
          class ConcreteUnevenFlyweight : Flyweight
          {
                    override public void DoOperation(int extrinsicState)
                    {
                               Console.WriteLine("In ConcreteUnevenFlyweight.DoOperation: {0}", extrinsicState);                         
                    }         
          }
 
          /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            int[] data = {1,2,3,4,5,6,7,8};
                               
                               FlyweightFactory f = new FlyweightFactory();
                               
                               int extrinsicState = 3;
                               foreach (int i in data)
                               {
                                         Flyweight flyweight = f.GetFlyweight(i);
                               flyweight.DoOperation(extrinsicState);
                               }
                               
            return 0;
        }
    }
}

名称

Proxy

结构

意图

为其他对象提供一种代理以控制对这个对象的访问。

适用性

  • 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用P r o x y 模式。下面是一 些可以使用P r o x y 模式常见情况:
    1) 远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用N X P r o x y 类实现了这一目的。Coplien[Cop92] 称这种代理为“大使” (A m b a s s a d o r )。
    2 )虚代理(Virtual Proxy )根据需要创建开销很大的对象。在动机一节描述的I m a g e P r o x y 就是这样一种代理的例子。
    3) 保护代理(Protection Proxy )控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。例如,在C h o i c e s 操作系统[ C I R M 9 3 ]中K e m e l P r o x i e s 为操作系统对象提供 了访问保护。
    4 )智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括:
  • 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为S m a r tP o i n t e r s[ E d e 9 2 ] )。
  • 当第一次引用一个持久对象时,将它装入内存。
  • 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

Code Example

namespace Proxy_DesignPattern
{
    using System;
          using System.Threading;
 
    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    abstract class CommonSubject 
          {
                    abstract public void Request();                    
          }
 
          class ActualSubject : CommonSubject
          {
                    public ActualSubject()
                    {
                               // Assume constructor here does some operation that takes quite a
                               // while - hence the need for a proxy - to delay incurring this 
                               // delay until (and if) the actual subject is needed
                               Console.WriteLine("Starting to construct ActualSubject");              
                               Thread.Sleep(1000); // represents lots of processing! 
                               Console.WriteLine("Finished constructing ActualSubject");
                    }
                               
                               override public void Request()
                    {
                               Console.WriteLine("Executing request in ActualSubject");
                    }
          }
 
          class Proxy : CommonSubject
          {
                    ActualSubject actualSubject;
 
                    override public void Request()
                    {
                               if (actualSubject == null)
                                         actualSubject = new ActualSubject();
                               actualSubject.Request();
                    }         
                    
          }
          
          public class Client
    {
        public static int Main(string[] args)
        {
                               Proxy p = new Proxy();
 
                               // Perform actions here
                               // . . . 
 
                               if (1==1)           // at some later point, based on a condition, 
                                         p.Request();// we determine if we need to use subject
                                                               
            return 0;
        }
    }
}

转载于:https://www.cnblogs.com/wangzhanjianshe/archive/2011/07/14/2326413.html

[置顶]c# 设计模式(2)结构型相关推荐

  1. 设计模式 之 结构型模式

    设计模式 之 结构型模式 模式 & 描述 包括 结构型模式 这些设计模式关注类和对象的组合.继承的概念被用来组合接口和定义组合对象获得新功能的方式. 适配器模式(Adapter Pattern ...

  2. Java设计模式之结构型:享元模式

    一.什么是享元模式: 享元模式通过共享技术有效地支持细粒度.状态变化小的对象复用,当系统中存在有多个相同的对象,那么只共享一份,不必每个都去实例化一个对象,极大地减少系统中对象的数量.比如说一个文本系 ...

  3. Java设计模式之结构型:组合模式

    前言: 我们对于上面两幅图片肯定非常熟悉,这两幅图片我们都可以看做是一个文件结构,对于这样的结构我们称之为树形结构.在数据结构中我们知道可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可 ...

  4. Java设计模式之结构型:外观模式

    一.什么是外观模式: 外观模式通过对客户端提供一个统一的接口,用于访问子系统中的一群接口.使用外观模式有以下几点好处: (1)更加易用:使得子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要 ...

  5. Java设计模式之结构型:代理模式

    前言: 我们一般在租房子时会去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做:再比如我们打官司需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们 ...

  6. Java设计模式之结构型:装饰器模式

    一.什么是装饰器模式: 当需要对类的功能进行拓展时,一般可以使用继承,但如果需要拓展的功能种类很繁多,那势必会生成很多子类,增加系统的复杂性,并且使用继承实现功能拓展时,我们必须能够预见这些拓展功能, ...

  7. Java设计模式之结构型:适配器模式

    一.什么是适配器模式: 适配器模式主要用于将一个类的接口转化成客户端希望的目标类格式,使得原本不兼容的类可以在一起工作,将目标类和适配者类解耦:同时也符合"开闭原则",可以在不修改 ...

  8. 备战面试日记(3.3) - (设计模式.23种设计模式之结构型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.9 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  9. 设计模式之结构型模型

    设计模式之结构型模型 桥接模式 尽可能不要使用类的继承,而尽可能使用 合成/聚合 描述: 继承方法子类与父类的高依赖性限制了复用和程序的灵活性. 选择不同的接口实现选择不同的业务类型 import o ...

  10. 组合模式(Bridge Pattern) – 设计模式之结构型模式

    组合模式(Bridge Pattern) – 设计模式之结构型模式: 目录 组合模式(Component Pattern) 类图 例子1: 过程: 类图: 代码: 抽象组件:PlayerComposi ...

最新文章

  1. oracle+测试权限,Oracle测试题
  2. 【Python】30天进阶Python!这个Github项目你值得拥有!
  3. Kruskal实现最小生成树
  4. 装机之MBR和GPT
  5. bootstrap table传回的数据后端怎么获取_基于 Spring Cloud 开发的分布式系统,遇到爬虫、接口盗刷怎么办
  6. oss图片尺寸调用方式_CDN百科11 | 如何用CDN加速OSS源站资源
  7. POJ3421:X-factor Chains——题解
  8. 【数字信号调制】基于matlab GUI数字信号调制仿真平台【含Matlab源码 880期】
  9. 常数除以0的极限是什么_【高数总结求极限方法】百度作业帮
  10. 安装office2013报安装程序找不到OneNote.zh-cn、安装源不存在
  11. CVPR 2019 论文汇总(按方向进行论文划分)
  12. 【Rust日报】 2019-04-27
  13. 数字版权资源价值日益凸显
  14. 计算机网络概述 第二部分
  15. 【转载】基于Office Online Server 2016 的office在线编辑
  16. JAVA SE面试题(全)
  17. Unity3d Ugui 15 TextMeshPro
  18. 谷歌出品开发必备开源图片压缩工具,终于知道图片压缩了啥
  19. synergy官方linux使用教程,使用 Synergy 来进行协同工作
  20. 前端知识点汇总、深入浅出

热门文章

  1. 报文交换(串行)和分组交换(并行)
  2. 排序算法的总结与使用题型
  3. bzoj 3392: [Usaco2005 Feb]Part Acquisition 交易(最短路)
  4. Codecraft-18 and Codeforces Round #458: C. Travelling Salesman and Sp(组合数)
  5. bzoj 1639: [Usaco2007 Mar]Monthly Expense 月度开支(二分)
  6. HDU 6170 2017 多校训练:Two strings(DP)
  7. java读取、生成图片
  8. 【node】node连接mongodb操作数据库
  9. 解决请求筛选模块被配置为拒绝包含的查询字符串过长的请求
  10. swift可选隐式可选类型