设计模式迷你手册 ---- RedSword软件工作室

RedSword软件工作室：http://redsword.cn.st

 | 创建型 | 结构型 | 行为型
类 | Factory Method | Adapter_Class | Interpreter Template Method
对象 | Abstract Factory Builder Prototype Singleton | Adapter_Object Bridge Composite Decorator Facade Flyweight Proxy | Chain of Responsibility Command Iterator Mediator Memento Observer State Strategy Visitor
概览 |

名称 | Factory Method
结构
意图 | 定义一个用于创建对象的接口，让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
适用性
  • 当一个类不知道它所必须创建的对象的类的时候。
  • 当一个类希望由它的子类来指定它所创建的对象的时候。
  • 当类将创建对象的职责委托给多个帮助子类中的某一个，并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
Code Example C++: factorymeth.cpp maze.cpp Geom.H MazeParts.H MazeFactories.H MazeFactory.H MazeGame.H defs.H
C#:factorymethod_designpattern.cs.txt

名称 | Abstract Factory
结构
意图 | 提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类。
适用性
  • 一个系统要独立于它的产品的创建、组合和表示时。
  • 一个系统要由多个产品系列中的一个来配置时。
  • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
  • 当你提供一个产品类库，而只想显示它们的接口而不是实现时。
Code Example C++: abfactory.cpp maze.cpp Geom.H MazeParts.H MazeFactories.H MazeFactory.H MazeGame.H defs.H
C#:abstractfactory_designpattern.cs.txt

名称 | Builder
结构
意图 | 将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。
适用性
  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。
Code Example C++: builder.cpp maze.cpp Geom.H MazeParts.H MazeFactories.H MazeFactory.H MazeGame.H defs.H
C#:builder_designpattern.cs.txt

名称 | Prototype
结构
意图 | 用原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象。
适用性
  • 当要实例化的类是在运行时刻指定时，例如，通过动态装载；或者
  • 为了避免创建一个与产品类层次平行的工厂类层次时；或者
  • 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
Code Example C++: prototype.cpp maze.cpp Geom.H MazeParts.H MazeFactories.H MazeFactory.H MazeGame.H defs.H
C#:prototype_designpattern.cs.txt

名称 | Singleton
结构
意图 | 保证一个类仅有一个实例，并提供一个访问它的全局访问点。
适用性
  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的，并且客户应该无需更改代码就能使用一个扩展的实例时。
Code Example C++: singleton.cpp maze.cpp Geom.H MazeParts.H MazeFactories.H MazeFactory.H MazeGame.H List.H Foundation.H
C#:singleton_designpattern.cs.txt

名称 | Adapter
结构

意图 | 将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性
  • 你想使用一个已经存在的类，而它的接口不符合你的需求。
  • 你想创建一个可以复用的类，该类可以与其他不相关的类或不可预见的类（即那些接口可能不一定兼容的类）协同工作。
  • （仅适用于对象A d a p t e r ）你想使用一些已经存在的子类，但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
Code Example C++: adapter.cpp Geom.H Foundation.H
C#:adapter_designpattern.cs.txt

名称 | 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 C++: bridge.cpp Geom.H Foundation.H
C#:bridge_designpattern.cs.txt

名称 | Composite
结构
意图 | 将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
适用性
  • 你想表示对象的部分-整体层次结构。
  • 你希望用户忽略组合对象与单个对象的不同，用户将统一地使用组合结构中的所有对象。
Code Example C++: composite.cpp List.H Foundation.H
C#:composite_designpattern.cs.txt

名称 | Decorator
结构
意图 | 动态地给一个对象添加一些额外的职责。就增加功能来说，D e c o r a t o r 模式相比生成子类更为灵活。
适用性
  • 在不影响其他对象的情况下，以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤消的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是，可能有大量独立的扩展，为支持每一种组合将产生大量的子类，使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏，或类定义不能用于生成子类。
Code Example C++: decorator.cpp
C#:decorator_designpattern.cs.txt

名称 | 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 C++: facade.cpp Foundation.H
C#:facade_designpattern.cs.txt

名称 | Flyweight
结构
意图 | 运用共享技术有效地支持大量细粒度的对象。
适用性
  • 一个应用程序使用了大量的对象。
  • 完全由于使用大量的对象，造成很大的存储开销。
  • 对象的大多数状态都可变为外部状态。
  • 如果删除对象的外部状态，那么可以用相对较少的共享对象取代很多组对象。
  • 应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享，对于概念上明显有别的对象，标识测试将返回真值。
Code Example C++: flyweight.cpp defs.H
C#:flyweight_designpattern.cs.txt

名称 | 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 C++: proxy.cpp Geom.H Foundation.H
C#:proxy_designpattern.cs.txt

名称 | Chain of Responsibility
结构
意图 | 使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递该请求，直到有一个对象处理它为止。
适用性
  • 有多个的对象可以处理一个请求，哪个对象处理该请求运行时刻自动确定。
  • 你想在不明确指定接收者的情况下，向多个对象中的一个提交一个请求。
  • 可处理一个请求的对象集合应被动态指定。
Code Example C++: chain.cpp defs.H
C#:chainofresponsibility_designpattern.cs.txt

名称 | Command
结构
意图 | 将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化；对请求排队或记录请求日志，以及支持可撤消的操作。
适用性
  • 抽象出待执行的动作以参数化某对象，你可用过程语言中的回调（c a l l b a c k ）函数表达这种参数化机制。所谓回调函数是指函数先在某处注册，而它将在稍后某个需要的时候被调用。C o m m a n d 模式是回调机制的一个面向对象的替代品。
  • 在不同的时刻指定、排列和执行请求。一个C o m m a n d 对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达，那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
  • 支持取消操作。C o m m a n d 的E x c u t e 操作可在实施操作前将状态存储起来，在取消操作时这个状态用来消除该操作的影响。C o m m a n d 接口必须添加一个U n e x e c u t e 操作，该操作取消上一次E x e c u t e 调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用U n e x e c u t e 和E x e c u t e 来实现重数不限的“取消”和“重做”。
  • 支持修改日志，这样当系统崩溃时，这些修改可以被重做一遍。在C o m m a n d 接口中添加装载操作和存储操作，可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用E x e c u t e 操作重新执行它们。
  • 用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务( t r a n s a c t i o n )的信息系统中很常见。一个事务封装了对数据的一组变动。C o m m a n d 模式提供了对事务进行建模的方法。C o m m a n d 有一个公共的接口，使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
Code Example C++: command.cpp List.H Foundation.H
C#:command_designpattern.cs.txt

名称 | Interpreter
结构
意图 | 给定一个语言，定义它的文法的一种表示，并定义一个解释器，这个解释器使用该表示来解释语言中的句子。
适用性
  • 当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时，可使用解释器模式。而当存在以下情况时该模式效果最好：
  • 该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。
  • 效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如，正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。
Code Example C++: interpreter.cpp defs.H
C#:interpreter_designpattern.cs.txt

名称 | Iterator
结构
意图 | 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性
  • 访问一个聚合对象的内容而无需暴露它的内部表示。
  • 支持对聚合对象的多种遍历。
  • 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
Code Example C++: iterator.cpp defs.H
C#:iterator_designpattern.cs.txt

名称 | Mediator
结构
意图 | 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。
适用性
  • 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
  • 想定制一个分布在多个类中的行为，而又不想生成太多的子类。
Code Example C++: mediator.cpp List.H Foundation.H
C#:mediator_designpattern.cs.txt

名称 | Memento
结构
意图 | 在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
适用性
  • 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
  • 如果一个用接口来让其它对象直接得到这些状态，将会暴露对象的实现细节并破坏对象的封装性。
Code Example C++: memento.cpp Geom.H Foundation.H
C#:memento_designpattern.cs.txt

名称 | Observer
结构
意图 | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性
  • 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象，而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
Code Example C++: observer.cpp List.H Foundation.H
C#:observer_designpattern.cs.txt

名称 | State
结构
意图 | 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用性
  • 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
  • 一个操作中含有庞大的多分支的条件语句，且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。S t a t e模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象，这一对象可以不依赖于其他对象而独立变化。
Code Example C++: state.cpp C++: TCPClosed.cpp
C#:state_designpattern.cs.txt

名称 | Strategy
结构
意图 | 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适用性
  • 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
  • 需要使用一个算法的不同变体。例如，你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时[ H O 8 7 ] ,可以使用策略模式。
  • 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
  • 一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的S t r a t e g y 类中以代替这些条件语句。
Code Example C++: strategy.cpp Geom.H Foundation.H
C#:strategy_designpattern.cs.txt

名称 | Template Method
结构
意图 | 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性
  • 一次性实现一个算法的不变的部分，并将可变的行为留给子类来实现。
  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是O p d y k e 和J o h n s o n 所描述过的“重分解以一般化”的一个很好的例子[ O J 9 3 ]。首先识别现有代码中的不同之处，并且将不同之处分离为新的操作。最后，用一个调用这些新的操作的模板方法来替换这些不同的代码。
  • 控制子类扩展。模板方法只在特定点调用“h o o k ”操作（参见效果一节），这样就只允许在这些点进行扩展。
Code Example C++: tmethod.cpp Foundation.H
C#:templatemethod_designpattern.cs.txt

名称 | Visitor
结构
意图 | 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性
  • 一个对象结构包含很多类对象，它们有不同的接口，而你想对这些对象实施一些依赖于其具体类的操作。
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作，而你想避免让这些操作“污染”这些对象的类。Vi s i t o r 使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时，用Vi s i t o r 模式让每个应用仅包含需要用到的操作。
  • 定义对象结构的类很少改变，但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口，这可能需要很大的代价。如果对象结构类经常改变，那么可能还是在这些类中定义这些操作较好。
Code Example C++: visitor.cpp Foundation.H
C#:visitor_designpattern.cs.txt

RedSword软件工作室：http://redsword.cn.st


// Abstract Factory

// Intent: "Provide an interface for creating families of related or
// dependent objects without specifying their concrete classes".

// For further information, read "Design Patterns", p87, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * When the construction needed involves many objects, possible organised
 * in multi-faceted arrangements, the entire construction can be delegated
 * to an abstract factory. This exposes standardised creation functionality
 * which can be customised in concrete implementation to suit your specific
 * needs, and avoid embedding this information in higher level code - it
 * just needs to know how to call the abstract factory.
 *
 * In this sample, we have a framework with three abstract operating classes,
 * called DPDocument, DPWorkspace and DPView and one abstract construction
 * class, called DPFactory. An application-level class, called DPApplication
 * is responsible for construction.
 *
 * We have a series of application-level operating classes derived from this
 * framework - MyDocument, MyWorkspace and MyView. For design reasons we
 * assume we wish to instantiate these from inside DPApplication. As there
 * are multiple objects needed and they could be arranged in different
 * lattices, we use a factory, MyFactory (in our example, there are all
 * simple siblings), which is called inside DPApplication.
 *
 */

namespace AbstractFactory_DesignPattern
{
    using System;

    // These classes could be part of a framework,
    // which we will call DP
    // ===========================================

    abstract class DPDocument
    {
        abstract public void Dump();
    }

    abstract class DPWorkspace
    {
        abstract public void Dump();
    }

    abstract class DPView
    {
        abstract public void Dump();
    }

    abstract class DPFactory
    {
        abstract public DPDocument CreateDocument();
        abstract public DPView CreateView();
        abstract public DPWorkspace CreateWorkspace();
    }

    abstract class DPApplication
    {
        protected DPDocument doc;
        protected DPWorkspace workspace;
        protected DPView view;

        public void ConstructObjects(DPFactory factory)
        {
            // Create objects as needed
            doc = factory.CreateDocument();
            workspace = factory.CreateWorkspace();
            view = factory.CreateView();
        }

        abstract public void Dump();

        public void DumpState()
        {
            if (doc != null) doc.Dump();
            if (workspace != null) workspace.Dump();
            if (view != null) view.Dump();
        }
    }

    // These classes could be part of an application
    class MyApplication : DPApplication
    {
        MyFactory myFactory = new MyFactory();

        override public void Dump()
        {
            Console.WriteLine("MyApplication exists");
        }

        public void CreateFamily()
        {
            MyFactory myFactory = new MyFactory();
            ConstructObjects(myFactory);
        }
    }

    class MyDocument : DPDocument
    {
        public MyDocument()
        {
                Console.WriteLine("in MyDocument constructor");
        }

        override public void Dump()
        {
            Console.WriteLine("MyDocument exists");
        }
    }

    class MyWorkspace : DPWorkspace
    {
        override public void Dump()
        {
            Console.WriteLine("MyWorkspace exists");
        }
    }

    class MyView : DPView
    {
        override public void Dump()
        {
            Console.WriteLine("MyView exists");
        }
    }

    class MyFactory : DPFactory
    {
        override public DPDocument CreateDocument()
        {
            return new MyDocument();
        }
        override public DPWorkspace CreateWorkspace()
        {
            return new MyWorkspace();
        }
        override public DPView CreateView()
        {
            return new MyView();
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            MyApplication myApplication = new MyApplication();

            myApplication.CreateFamily();

            myApplication.DumpState();

            return 0;
        }
    }
}


// Adapter

// Intent: "Convert the interface of a class into another interface
// clients expect. Adapter lets classes work together that couldn't
// otherwise because of incompatible interfaces".

// For further information, read "Design Patterns", p139, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Adapters are often used when client code is written to expect classes
 * from one framework, and it meant to work with classes from a totally
 * different framework. Assume you cannot change the code of either framework.
 * the solution is for you to write an adapter, which appears like a
 * native class to each framework.
 *
 * There are two different types of adapters - class adapter and object
 * adapter. Class adapters are based on multiple inheritance - specifically
 * the interface of the target class and the implementation of the adaptee.
 * Unfortunately C# supports multiple inheritance for interfaces but not
 * for classes. Object adapters derive from the target (single inheritance)
 * and maintain a private instance of the adoptee.
 *
 * The sample code here shows an object adapter. We have a class called
 * FrameworkYAdaptee which we wish to use, yet the (bulk of) the client code
 * (in GenericClientCode) is written to expect a class called FrameworkXTarget.
 * To solve the probelm we create an Adapter class, which it a FrameworkXTarget
 * to the client, and calls FrameworkYAdaptee.
 *
 */

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

// Intent: "Decouple an abstraction from its implemntation so that the
// two can vary independently".

// For further information, read "Design Patterns", p151, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Coupling between classes and class libraries is a major maintenance
 * headache. To ease this problem, often the client talks to an
 * abstraction description, which in turn calls an implementation.
 * Sometimes these must evolve - when one changes there can be a need
 * to change the other.  The bridge design pattern lets the abstraction
 * and its implementation evolve separately.
 *
 * So, what is the difference between a bridge and an interface? Interfaces
 * can be used when creating bridges - but it should be noted that bridges
 * have additional possibilities. Both the abstraction and the
 * implementation may evolve over time and be the parent of derived classes.
 * The operations needed in the implementation could be defined in an
 * interface if there are no standard methods which are available at the
 * top-level of the implementation.
 *
 */

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;
        }
    }
}


// Builder

// Intent: "Separate the construction of a complex object from its
// representation so that the same construction process can create
// different representations".

// For further information, read "Design Patterns", p97, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Builder is an object creational design pattern that codifies the
 * construction process outside of the actual steps that carries out
 * the construction - thus allowing the construction process itself
 * to be reused.
 *
 */

namespace Builder_DesignPattern
{
    using System;

    // These two classes could be part of a framework,
    // which we will call DP
    // ===============================================

    class Director
    {
        public void Construct(AbstractBuilder abstractBuilder)
        {
            abstractBuilder.BuildPartA();
            if (1==1 ) //represents some local decision inside director
            {
                abstractBuilder.BuildPartB();
            }
            abstractBuilder.BuildPartC();
        }

    }

    abstract class AbstractBuilder
    {
        abstract public void BuildPartA();
        abstract public void BuildPartB();
        abstract public void BuildPartC();
    }

    // These two classes could be part of an application
    // =================================================

    class ConcreteBuilder : AbstractBuilder
    {
        override public void BuildPartA()
        {
            // Create some object here known to ConcreteBuilder
            Console.WriteLine("ConcreteBuilder.BuildPartA called");
        }

        override public void BuildPartB()
        {
            // Create some object here known to ConcreteBuilder
            Console.WriteLine("ConcreteBuilder.BuildPartB called");
        }

        override public void BuildPartC()
        {
            // Create some object here known to ConcreteBuilder
            Console.WriteLine("ConcreteBuilder.BuildPartC called");
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            ConcreteBuilder concreteBuilder = new ConcreteBuilder();
            Director director = new Director();

            director.Construct(concreteBuilder);

            return 0;
        }
    }
}


// Chain Of Responsibility

// Intent: "Avoid coupling the sender of a request to its receiver by giving
// more than one object a chance to handle the reuqest. Chain the receiving
// objects and pass the request along the chain until an object handles it."

// For further information, read "Design Patterns", p223, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * The client sends a request and it will be operated on by one of a number
 * of potential receivers, in a chain. The client does not know (and does
 * not need to know) which receiver handles the request. The receivers are
 * in a chain, and the request is passed from one to the next, until one
 * receiver actually performs the request.
 */

namespace ChainOfResponsibility_DesignPattern
{
    using System;

    abstract class Handler
    {
        protected Handler successorHandler;
        abstract public void HandleRequest(Request request);
        public void SetSuccessor(Handler sucessor)
        {
            successorHandler = sucessor;
        }
    }

    class ConcreteHandler1 : Handler
    {
        override public void HandleRequest(Request request)
        {
            // determine if we can handle the request
            if (request.RequestType == 1) // some complex decision making!
            {
                // request handling code goes here
                Console.WriteLine("request handled in ConcreteHandler1");
            }
            else
            {
                // not handled here - pass on to next in the chain
                if (successorHandler != null)
                    successorHandler.HandleRequest(request);
            }
        }
    }

    class ConcreteHandler2 : Handler
    {
        override public void HandleRequest(Request request)
        {
            // determine if we can handle the request
            if (request.RequestType == 2) // some complex decision making!
            {
                // request handling code goes here
                Console.WriteLine("request handled in ConcreteHandler2");
            }
            else
            {
                // not handled here - pass on to next in the chain
                if (successorHandler != null)
                    successorHandler.HandleRequest(request);
            }
        }
    }

    class ConcreteHandler3 : Handler
    {
        override public void HandleRequest(Request request)
        {
            // determine if we can handle the request
            if (request.RequestType == 3) // some complex decision making!
            {
                // request handling code goes here
                Console.WriteLine("request handled in ConcreteHandler3");
            }
            else
            {
                // not handled here - pass on to next in the chain
                if (successorHandler != null)
                    successorHandler.HandleRequest(request);
            }
        }
    }

    class Request
    {
        private int iRequestType;
        private string strRequestParameters;

        public Request(int requestType, string requestParameters)
        {
            iRequestType = requestType;
            strRequestParameters = requestParameters;
        }

        public int RequestType
        {
            get
            {
                return iRequestType;
            }
            set
            {
                iRequestType = value;
            }
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            // Set up chain (usually one need to be done once)
            Handler firstHandler = new ConcreteHandler1();
            Handler secondHandler = new ConcreteHandler2();
            Handler thirdHandler = new ConcreteHandler3();
            firstHandler.SetSuccessor(secondHandler);
            secondHandler.SetSuccessor(thirdHandler);

            // After setting up the chain of responsibility, we can
            // now generate requests and pass then off to the
            // chain to be handled

            // generate and fire request
            Request newRequest = new Request(2,"This are the request parameters");
            firstHandler.HandleRequest(newRequest);

            return 0;
        }
    }
}


// Command

// Intent: "Encapsulate a request as an object, thereby letting you
// parameterize clients with different requests, queue or log
// requests, and support undoable operations".

// For further information, read "Design Patterns", p233, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Commands are at the heart of a modern GUI app.
 * They must be nameable, undoable, recordable,
 * configurable, executable and repeatable.
 *
 * In addition to the command here, a command type could also be useful.
 * It could store the name of a command, information about its icon, etc.
 */

namespace Command_DesignPattern
{
    using System;

    abstract class Command
    {
        abstract public void Execute();
        protected Receiver r;
        public Receiver R
        {
            set
            {
                r = value;
            }
        }
    }

    class ConcreteCommand : Command
    {
        override public void Execute()
        {
            Console.WriteLine("Command executed");
            r.InformAboutCommand();
        }
    }

    class Receiver
    {
        public void InformAboutCommand()
        {
            Console.WriteLine("Receiver informed about command");
        }

    }

    class Invoker
    {
        private Command command;
        public void StoreCommand(Command c)
        {
            command = c;
        }
        public void ExecuteCommand()
        {
            command.Execute();
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            // Set up everything
            Command c = new ConcreteCommand();
            Receiver r = new Receiver();
            c.R = r;
            Invoker i = new Invoker();
            i.StoreCommand(c);

            // now let application run

            // the invoker is how the command is exposed for the end-user
            // (or a client) initiates the command,
            // (e.g. toolbar button, menu item)

            i.ExecuteCommand();

            return 0;
        }
    }
}


// Composite

// Intent: "Compose objects into tree structures to represent part-whole
// hierarchies. Composite lets clients treat individual objects and
// compositions of objects uniformly".

// For further information, read "Design Patterns", p163, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * We often have tree structures where some nodes are containers of
 * other nodes, and some nodes are leafs. Rather than have separate client
 * code to manage each type of node, Composite lets a client work with
 * either using the same code.
 *
 * There is an excellent discussion to be found in "Pattern Hatching",
 * Vlissides, ISBN: 0-201-43293-5, describing how the Composite design
 * pattern can be used as the basis file system management
 * (directory = composite, Leaf = file, Component = iNode)
 *
 */

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

// Intent: "Attach additional responsibilites to an object dynamically.
// Decorators provide a flexible alternative to subclassing for
// extending functionality".

// For further information, read "Design Patterns", p175, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Dynamically wrap functionality with additonal functionality, so that
 * the client does not know the difference.
 */

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

// Intent: "Provide a unified interface to a set of interfaces in a subsystem.
// Facade defines a higher-level interface that makes the subsystem easier
// to use".

// For further information, read "Design Patterns", p185, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Many subsystems are complex to manage - and this is a dis-incentive for
 * client code to use them. A Facasde design pattern provides a simlified
 * high-level API to the client, thus shielding it from direct contact
 * with the (more complex) subsystem classes.
 *
 * Often the code that is inside a facade would have to be inside client
 * code without the facade. The subsystem code beneath the facade can
 * change, without affecting the client code.
 */

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;
        }
    }
}


// Factory Method

// Intent: "Define an interface for creating an object, but let subclasses
// decide which class to instantiate. Factory Method lets a class defer
// instantiation to subclasses".

// For further information, read "Design Patterns", p107, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * This design pattern is often used in a framework architecture, which
 * contains a number of related classes inside the framework, and which
 * expects application developers to derive custom classes from them.
 * If the instantiation of some custom application classes needs to be
 * carried out inside framework code, then the Factory Method design
 * pattern is an ideal solution.
 *
 * The sample below is based on a document view architecture.
 * It shows the framework providing classes DPApplication and DPDocument
 * and the application providing MyApplication and MyDocument, derived
 * from the corresponding framework classes. Note how the construction
 * of MyDocument is initiated from inside the framework's DPApplication,
 * yet the framework was not written specifically for it.
 *
 * It could be extended for views and workspaces along the same lines.
 */

namespace FactoryMethod_DesignPattern
{
    using System;

    // These two classes could be part of a framework,
    // which we will call DP
    // ===============================================

    class DPDocument
    {

    }

    abstract class DPApplication
    {
        protected DPDocument doc;

        abstract public void CreateDocument();

        public void ConstructObjects()
        {

            // Create objects as needed
            // . . .

            // including document
            CreateDocument();
        }
        abstract public void Dump();
    }

    // These two classes could be part of an application
    // =================================================

    class MyApplication : DPApplication
    {
        override public void CreateDocument()
        {
            doc = new MyDocument();
        }

        override public void Dump()
        {
            Console.WriteLine("MyApplication exists");
        }
    }

    class MyDocument : DPDocument
    {

    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            MyApplication myApplication = new MyApplication();

            myApplication.ConstructObjects();

            myApplication.Dump();

            return 0;
        }
    }
}


// Flyweight

// Intent: "Use sharing to support large numbers of fine-grained objects effectively".

// For further information, read "Design Patterns", p195, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Useful patetn when you have a small(ish) number of objects that might be
 * needed a very large number of times - with slightly differnt informaiton,
 * that can be externalised outside those objects.
 */

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;
        }
    }
}


// Interpreter

// Intent: "Given a language, define a representation for its grammar along
// with an interpreter that uses the representation to interpret
// sentences in the language".

// For further information, read "Design Patterns", p243, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * This is used to implement a language using a class hierarchy
 */

namespace Interpreter_DesignPattern
{
    using System;
    using System.Collections;

    class Context
    {

    }

    abstract class AbstractExpression
    {
        abstract public void Interpret(Context c);
    }

    // class for terminal symbol
    class TerminalExpression : AbstractExpression
    {
        override public void Interpret(Context c)
        {

        }
    }

    // class for grammar rule (one per rule needed)
    class NonterminalExpression : AbstractExpression
    {
        override public void Interpret(Context c)
        {

        }
    }
    // to extend grammar, just add other NonterminalExpression classes

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            Context c = new Context();
            ArrayList l = new ArrayList(); //really need a tree here!

            // build up context information
            // . . .

            // Populate abstract syntax tree with data
            l.Add(new TerminalExpression());
            l.Add(new NonterminalExpression());

            // interpret
            foreach (AbstractExpression exp in l)
            {
                exp.Interpret(c);
            }

            return 0;
        }
    }
}


// Iterator

// Intent: "Provide a way to access the elements of an aggregate object
// sequentially without exposing its underlying representation".

// For further information, read "Design Patterns", p257, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Here wish wish to separate node traversal from the nodes themselves.
 * STL in ISO C++ is a highly successful application of this pattern.
 * Generic programming is a great way to implement iterators. As this is
 * not yet in C#, we use inheritance.
 *
 */

namespace Iterator_DesignPattern
{
    using System;
    using System.Collections;

    class Node
    {
        private string name;
        public string Name
        {
            get
            {
                return name;
            }
        }
        public Node(string s)
        {
            name = s;
        }
    }

    class NodeCollection
    {
        private ArrayList list = new ArrayList();
        private int nodeMax = 0;

        // left as a student exercise - implement collection
        // functions to remove and edit entries also
        public void AddNode(Node n)
        {
            list.Add(n);
            nodeMax++;
        }
        public Node GetNode(int i)
        {
            return ((Node) list[i]);
        }

        public int NodeMax
        {
            get
            {
                return nodeMax;
            }
        }
    }

    /*
     * The iterator needs to understand how to traverse the collection
     * It can do that as way it pleases - forward, reverse, depth-first,
     */
    abstract class Iterator
    {
        abstract public Node Next();
    }

    class ReverseIterator : Iterator
    {
        private NodeCollection nodeCollection;
        private int currentIndex;

        public ReverseIterator (NodeCollection c)
        {
            nodeCollection = c;
            currentIndex = c.NodeMax -1; // array index starts at 0!
        }

        // note: as the code stands, if the collection changes,
        // the iterator needs to be restarted
        override public Node Next()
        {
            if (currentIndex == -1)
                return null;
            else
                return(nodeCollection.GetNode(currentIndex--));
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            NodeCollection c = new NodeCollection();
            c.AddNode(new Node("first"));
            c.AddNode(new Node("second"));
            c.AddNode(new Node("third"));

            // now use iterator to traverse this
            ReverseIterator i = new ReverseIterator(c);

            // the code below will work with any iterator type
            Node n;
            do
            {
                n = i.Next();
                if (n != null)
                    Console.WriteLine("{0}", n.Name);
            } while (n != null);

            return 0;
        }
    }
}


// Mediator

// Intent: "Define an object that encapsulates how a set of objects interact.
// Mediator promotes loose coupling by keeping objects from referring to each
// other explicitly, and it lets you vary their interaction independently."

// For further information, read "Design Patterns", p273, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Consider a mediator as a hub, which objects that need to talk -
 * but do not wish to be interdependent - can use.
 */

namespace Mediator_DesignPattern
{
    using System;

    class Mediator
    {
        private DataProviderColleague dataProvider;
        private DataConsumerColleague dataConsumer;
        public void IntroduceColleagues(DataProviderColleague c1, DataConsumerColleague c2)
        {
            dataProvider = c1;
            dataConsumer = c2;
        }

        public void DataChanged()
        {
            int i = dataProvider.MyData;
            dataConsumer.NewValue(i);
        }
    }

    class DataConsumerColleague
    {
        public void NewValue(int i)
        {
            Console.WriteLine("New value {0}", i);
        }
    }

    class DataProviderColleague
    {
        private Mediator mediator;
        private int iMyData=0;
        public int MyData
        {
            get
            {
                return iMyData;
            }
            set
            {
                iMyData = value;
            }
        }
        public DataProviderColleague(Mediator m)
        {
            mediator = m;
        }

        public void ChangeData()
        {
            iMyData = 403;

            // Inform mediator that I have changed the data
            if (mediator != null)
                mediator.DataChanged();
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            Mediator m = new Mediator();
            DataProviderColleague c1 = new DataProviderColleague(m);
            DataConsumerColleague c2 = new DataConsumerColleague();
            m.IntroduceColleagues(c1,c2);

            c1.ChangeData();

            return 0;
        }
    }
}


// Memento

// Intent: "Without violating encapsulation, capture and externalize an
// object's internal state so that an object can be restored to this
// state later."

// For further information, read "Design Patterns", p283, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * We often have client code that wishes to record the current state of an
 * object, without being interested in the actual data values (this is
 * needed for undo and checkpointing). To support this behavior, we can have
 * the object record its internal data in a helper class called a memento, and
 * the client code can treat this as an opaque store of the object's state.
 * At some later point, the client can pass the memento back into the object,
 * to restore it to the previous state.
 */

namespace Memento_DesignPattern
{
    using System;

    class Originator
    {
        private double manufacturer=0;
        private double distributor = 0;
        private double retailer = 0;

        public void MakeSale(double purchasePrice)
        {
            // We assume sales are divided equally amount the three
            manufacturer += purchasePrice * .40;
            distributor += purchasePrice *.3;
            retailer += purchasePrice *.3;
            // Note: to avoid rounding errors for real money handling
            // apps, we should be using decimal integers
            // (but hey, this is just a demo!)
        }

        public Memento CreateMemento()
        {
            return (new Memento(manufacturer, distributor, retailer));
        }

        public void SetMemento(Memento m)
        {
            manufacturer = m.A;
            distributor = m.B;
            retailer = m.C;
        }
    }

    class Memento
    {
        private double iA;
        private double iB;
        private double iC;

        public Memento(double a, double b, double c)
        {
            iA = a;
            iB = b;
            iC = c;
        }

        public double A
        {
            get
            {
                return iA;
            }
        }

        public double B
        {
            get
            {
                return iB;
            }
        }

        public double C
        {
            get
            {
                return iC;
            }
        }
    }

    class caretaker
    {

    }

        /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            Originator o = new Originator();

            // Assume that during the course of running an application
            // we we set various data in the originator
            o.MakeSale(45.0);
            o.MakeSale(60.0);

            // Now we wish to record the state of the object
            Memento m = o.CreateMemento();

            // We make further changes to the object
            o.MakeSale(60.0);
            o.MakeSale(10.0);
            o.MakeSale(320.0);

            // Then we decide ot change our minds, and revert to the saved state (and lose the changes since then)
            o.SetMemento(m);

            return 0;
        }
    }
}


// Observer

// Intent: "Define a one-to-many dependency between objects so that when one
// object changes state, all its dependents are notified and
// updated automatically".

// For further information, read "Design Patterns", p293, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Often used for Document-View architectures, where a document stores
 * data and one or more views renders the data.
 */

namespace Observer_DesignPattern
{
    using System;
    using System.Collections;

    class Subject
    {
        private ArrayList list = new ArrayList();

        private string strImportantSubjectData = "Initial";

        public string ImportantSubjectData
        {
            get
            {
                return strImportantSubjectData;
            }
            set
            {
                strImportantSubjectData = value;
            }
        }

        public void Attach(Observer o)
        {
            list.Add(o);
            o.ObservedSubject = this;
        }

        public void Detach(Observer o)
        {

        }

        public void Notify()
        {
            foreach (Observer o in list)
            {
                o.Update();
            }
        }
    }

    class ConcreteSubject : Subject
    {
        public void GetState()
        {

        }

        public void SetState()
        {

        }
    }

    abstract class Observer
    {
        protected Subject s;
        public Subject ObservedSubject
        {
            get
            {
                return s;
            }
            set
            {
                s = value;
            }
        }
        abstract public void Update();
    }

    class ConcreteObserver : Observer
    {
        private string observerName;

        public ConcreteObserver(string name)
        {
            observerName = name;
        }

        override public void Update()
        {
            Console.WriteLine("In Observer {0}: data from subject = {1}",
                observerName, s.ImportantSubjectData);
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            // Set up everything
            ConcreteSubject s = new ConcreteSubject();
            ConcreteObserver o1 = new ConcreteObserver("first observer");
            ConcreteObserver o2 = new ConcreteObserver("second observer");

            s.Attach(o1);
            s.Attach(o2);

            // make changes to subject
            s. ImportantSubjectData = "This is important subject data";

            // Notify all observers
            s.Notify();
            return 0;
        }
    }
}


// Prototype

// Intent: "Specify the kinds of objects to create using a prototypical
// instance and create new objects by copying this prototype".

// For further information, read "Design Patterns", p117, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * When we are not in a position to call a constructor for an object
 * directly, we could alternatively clone a pre-existing object
 * (a prototype) of the same class.
 *
 * This results in specific class knowledge being only required in
 * one area (to create the prototype itself), and then later cloned
 * from code that knows nothing about the cloned prototype, except
 * that it exposed a well-known cloning method.
 *
 */

namespace Prototype_DesignPattern
{
    using System;

    // Objects which are to work as prototypes must be based on classes which
    // are derived from the abstract prototype class
    abstract class AbstractPrototype
    {
        abstract public AbstractPrototype CloneYourself();
    }

    // This is a sample object
    class MyPrototype : AbstractPrototype
    {
        override public AbstractPrototype CloneYourself()
        {
            return ((AbstractPrototype)MemberwiseClone());
        }
        // lots of other functions go here!
    }

    // This is the client piece of code which instantiate objects
    // based on a prototype.
    class Demo
    {
        private AbstractPrototype internalPrototype;

        public void SetPrototype(AbstractPrototype thePrototype)
        {
            internalPrototype = thePrototype;
        }

        public void SomeImportantOperation()
        {
            // During Some important operation, imagine we need
            // to instantiate an object - but we do not know which. We use
            // the predefined prototype object, and ask it to clone itself.

            AbstractPrototype x;
            x = internalPrototype.CloneYourself();
            // now we have two instances of the class which as as a prototype
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            Demo demo = new Demo();
            MyPrototype clientPrototype = new MyPrototype();
            demo.SetPrototype(clientPrototype);
            demo.SomeImportantOperation();

            return 0;
        }
    }
}


// Factory Method

// Intent: "Provide a surrogate or placeholder for another object to
// control access to it".

// For further information, read "Design Patterns", p207, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * When there is a large CPU/memory expense attached to handling an object
 * directly, it can be useful to use a lightweight proxy in front of it,
 * which can take its place until the real object is needed.
 */

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;
        }
    }
}


// Singleton

// Intent: "Ensure a class only has one instance, and provide a global
// point of access to it".

// For further information, read "Design Patterns", p127, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * If it makes sense to have only a single instance of a class (a so-called
 * singleton), then it makes sense to enforce this (to elimintate potential
 * errors, etc).
 *
 * A class based on the singleton design pattern protects its constructor,
 * so that only the class itself (e.g. in a static method) may instantiate itself.
 * It exposes an Instance method which allows client code to retrieve the
 * current instance, and if it does not exist to instantiate it.
 */

namespace Singleton_DesignPattern
{
    using System;

    class Singleton
    {
        private static Singleton _instance;

        public static Singleton Instance()
        {
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
        }
        protected Singleton(){}

        // Just to prove only a single instance exists
        private int x = 0;
        public void SetX(int newVal) {x = newVal;}
        public int GetX(){return x;}
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            int val;
            // can't call new, because constructor is protected
            Singleton FirstSingleton = Singleton.Instance();
            Singleton SecondSingleton = Singleton.Instance();

            // Now we have two variables, but both should refer to the same object
            // Let's prove this, by setting a value using one variable, and
            // (hopefully!) retrieving the same value using the second variable
            FirstSingleton.SetX(4);
            Console.WriteLine("Using first variable for singleton, set x to 4");

            val = SecondSingleton.GetX();
            Console.WriteLine("Using second variable for singleton, value retrieved = {0}", val);
            return 0;
        }
    }
}


// State

// Intent: "Allow an object to alter its behavior when its internal state
// changes. The object will appear to change its class".

// For further information, read "Design Patterns", p305, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 *
 * A finite state machine is an appropriate construct to use for a class whose
 * reaction to stimuli depends on previous behavior. In the past, each
 * method in the class was coded as a switch statement, switching on the state.
 * If a new state was added, then each method had to be edited.
 *
 * With the state design pattern, functionality specific to a state is placed
 * in a helper class, and the main class delegates those methods that are
 * state-specific to such helper classes.
 *
 */

namespace State_DesignPattern
{
    using System;

    abstract class State
    {
        protected string strStatename;

        abstract public void Pour();
        // do something state-specific here
    }

    class OpenedState : State
    {
        public OpenedState ()
        {
            strStatename = "Opened";
        }
        override public void Pour()
        {
            Console.WriteLine("...pouring...");
            Console.WriteLine("...pouring...");
            Console.WriteLine("...pouring...");
        }
    }

    class ClosedState : State
    {
        public ClosedState()
        {
            strStatename = "Closed";
        }
        override public void Pour()
        {
            Console.WriteLine("ERROR - bottle is closed - cannot pour");
        }
    }

    class ContextColaBottle
    {
        public enum BottleStateSetting {
            Closed,
            Opened
        };

        // If teh state classes had large amounts of instance data,
        // we could dynamically create them as needed - if this demo
        // they are tiny, so we just  create them as data members
        OpenedState openedState = new OpenedState();
        ClosedState closedState = new ClosedState();

        public ContextColaBottle ()
        {
            // Initialize to closed
            CurrentState = closedState;
        }

        private State CurrentState;

        public void SetState(BottleStateSetting newState)
        {
            if (newState == BottleStateSetting.Closed)
            {
                CurrentState = closedState;
            }
            else
            {
                CurrentState = openedState;
            }
        }

        public void Pour()
        {
            CurrentState.Pour();
        }
    }

      /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            ContextColaBottle contextColaBottle = new ContextColaBottle();

            Console.WriteLine("initial state is closed");

            Console.WriteLine("Now trying to pour");
              contextColaBottle.Pour();

            Console.WriteLine("Open bottle");
            contextColaBottle.SetState(ContextColaBottle.BottleStateSetting.Opened);

            Console.WriteLine("Try to pour again");
            contextColaBottle.Pour();

            return 0;
        }
    }
}


// Strategy

// Intent: "Define a family of algorithms, encapsultate each one, and make
// them interchangeable. Strategy lets the algorithm vary independently
// from clients that use it."

// For further information, read "Design Patterns", p315, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * Ideal for creating exchangeable algorithms.
 */

namespace Strategy_DesignPattern
{
    using System;

    abstract class Strategy
    {
        abstract public void DoAlgorithm();
    }

    class FirstStrategy : Strategy
    {
        override public void DoAlgorithm()
        {
            Console.WriteLine("In first strategy");
        }
    }

    class SecondStrategy : Strategy
    {
        override public void DoAlgorithm()
        {
            Console.WriteLine("In second strategy");
        }
    }

    class Context
    {
        Strategy s;
        public Context(Strategy strat)
        {
            s = strat;
        }

        public void DoWork()
        {
            // some of the context's own code goes here
        }

        public void DoStrategyWork()
        {
            // now we can hand off to the strategy to do some
            // more work
            s.DoAlgorithm();
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            FirstStrategy firstStrategy = new FirstStrategy();
            Context c = new Context(firstStrategy);
            c.DoWork();
            c.DoStrategyWork();

            return 0;
        }
    }
}


// Template Method

// Intent: "Define the skeleton of an algorithm in an operation, deferring
// some steps to subclasses. Template Method lets subclasses redefine
// certain steps of an algorithm without changing the algorithm's structure."

// For further information, read "Design Patterns", p325, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * If you have an algorithm with multiple steps, and it could be helpful
 * to make some of those steps replaceable, but no the entire algorithm, then
 * use the Template method.
 *
 * If the programming language in use supports generics / templates (C# does
 * not), then they could be used here. It would be educational to take a
 * good look at the way algorithms in ISO C++'s STL work.
 */

namespace TemplateMethod_DesignPattern
{
    using System;

    class Algorithm
    {
        public void DoAlgorithm()
        {
            Console.WriteLine("In DoAlgorithm");

            // do some part of the algorithm here

            // step1 goes here
            Console.WriteLine("In Algorithm - DoAlgoStep1");
            // . . .

            // step 2 goes here
            Console.WriteLine("In Algorithm - DoAlgoStep2");
            // . . .

            // Now call configurable/replacable part
            DoAlgoStep3();

            // step 4 goes here
            Console.WriteLine("In Algorithm - DoAlgoStep4");
            // . . .

            // Now call next configurable part
            DoAlgoStep5();
        }

        virtual public void DoAlgoStep3()
        {
            Console.WriteLine("In Algorithm - DoAlgoStep3");
        }

        virtual public void DoAlgoStep5()
        {
            Console.WriteLine("In Algorithm - DoAlgoStep5");
        }
    }

    class CustomAlgorithm : Algorithm
    {
        public override void DoAlgoStep3()
        {
            Console.WriteLine("In CustomAlgorithm - DoAlgoStep3");
        }

        public override void DoAlgoStep5()
        {
            Console.WriteLine("In CustomAlgorithm - DoAlgoStep5");
        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            CustomAlgorithm c = new CustomAlgorithm();

            c.DoAlgorithm();

            return 0;
        }
    }
}


// Visitor

// Intent: "Represent an operation to be performed on the elements of an
// object structure. Visitor lets you define a new operation without
// changing the classes of the elements on which it operates."

// For further information, read "Design Patterns", p331, Gamma et al.,
// Addison-Wesley, ISBN:0-201-63361-2

/* Notes:
 * If you have a number of elements, and wish to carry out a number of
 * operations on them, the Visitor design pattern can be helpful.
 *
 * It lets you extract the operations to be carried out on elements from
 * the elements themselves. It means operations cna change without affecting
 * the elements.
 */

namespace Visitor_DesignPattern
{
    using System;

    abstract class Visitor
    {
        abstract public void VisitElementA(ConcreteElementA a);
        abstract public void VisitElementB(ConcreteElementB b);
    }

    class ConcreteVisitor1 : Visitor
    {
        override public void VisitElementA(ConcreteElementA a)
        {

        }

        override public void VisitElementB(ConcreteElementB b)
        {

        }
    }

    abstract class Element
    {
        abstract public void Accept(Visitor v);
    }

    class ConcreteElementA : Element
    {
        public Visitor myVisitor;
        override public void Accept(Visitor v)
        {
            myVisitor = v;
        }

        public void OperationA()
        {

        }

        public void DoSomeWork()
        {
            // do some work here
            // . . .

            // Get visitor to visit
            myVisitor.VisitElementA(this);

            // do some more work here
            // . . .
        }
    }

    class ConcreteElementB : Element
    {
        override public void Accept(Visitor v)
        {

        }

        public void OperationB()
        {

        }
    }

    /// <summary>
    ///    Summary description for Client.
    /// </summary>
    public class Client
    {
        public static int Main(string[] args)
        {
            ConcreteElementA eA = new ConcreteElementA();
            ConcreteElementB eB = new ConcreteElementB();
            ConcreteVisitor1 v1 = new ConcreteVisitor1();

            eA.Accept(v1);
            eA.DoSomeWork();

            return 0;
        }
    }
}