[设计模式|C#&Java]设计模式学习笔记

文章目录

  • 设计原则
    • 1. 开闭原则
    • 2. 单一原则
    • 3. 接口隔离原则
    • 4. 依赖倒转原则
    • 5. 里氏替换原则
    • 6. 迪米特法则(最少知道原则)
    • 7. 合成复用原则
  • 一、创建模式
    • 1. 单例模式
    • 2、工厂模式
      • Java Demo
      • C# Demo
    • 3.抽象工厂
      • Java Demo
    • 4、原型模式
    • 5、建造者模式
      • Java Demo
      • C# Demo
  • 二、结构模式
    • 1、适配器模式
    • 2、桥接模式
      • Java Demo
      • C# Demo
    • 3、装饰器模式
    • 4、组合模式
    • 5、外观模式
    • 6、享元模式
    • 7、代理模式
  • 三、行为模式
    • 1、模板方法模式
    • 2、命令模式
      • Java Demo
      • C# Demo
    • 3、访问者模式
      • Java Demo
      • C# Demo
    • 4、迭代器模式
    • 5、观测者模式
    • 6、中介模式
    • 7、备忘录模式
    • 8、解释器模式
      • Java Demo
    • 9、状态模式
      • Java Demo
    • 10、策略模式
    • 11、职责链模式

设计原则

1. 开闭原则

对扩展开放,对修改封闭,当增加功能时候,尽量不要去修改原来的代码,而是去增加方法或者增加新类。比如说有一个Object类,已经定义好了三种方法,那就不要再去修改三种方法的代码了,但是可以在类中再定义其他的方法,比如methoid4()等等或者新建一个新类,新类可以继承Object或者聚合Object,保证不会影响已经使用了Object类的代码功能,同时又扩展了Object类的功能。

Class Object:
	def methoid1():
		pass
	def methoid2():
		pass
	def methoid3():
		pass

2. 单一原则

当且仅当类中的方法很简单的时候,可以只采用方法单一原则,否则就应严格采用类功能单一原则。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.principle
{
    class SingleResponsibility
    {
        static void Main(string[] args)
        {
            Vehicle vehicle = new Vehicle();
            vehicle.run("Car");
            vehicle.dive("Ship");
            vehicle.fly("Airplane");
            RoadVehicle car = new RoadVehicle();
            car.run();
            WaterVehicle ship = new WaterVehicle();
            ship.run();
            AirVehicle plane = new AirVehicle();
            plane.run();
        }
    }

    #region 方法单一原则
    public class Vehicle
    {
        public void run(string vehicle)
        {
            Console.WriteLine(vehicle + "running on the road...");
        }
        public void fly(string vehicle)
        {
            Console.WriteLine(vehicle + "flying in the air...");
        }
        public void dive(string vehicle)
        {
            Console.WriteLine(vehicle + "diving in the water...");
        }
    }
    #endregion
    #region 严格的单一原则
    public class RoadVehicle
    {
        public void run()
        {
            Console.WriteLine("Vehicle is runing on the road...");
        }
    }
    public class WaterVehicle
    {
        public void run()
        {
            Console.WriteLine("Vehicle is surfing in the water...");
        }
    }
    public class AirVehicle
    {
        public void run()
        {
            Console.WriteLine("Vehicle is flying in the air...");
        }
    }
    #endregion
}

3. 接口隔离原则

依赖的接口方法尽量要全部实现,不能实现的就把接口分离出来
可以用抽象类实现接口,然后实例化类再继承抽象类,有针对性的实现需要的方法,不需要的就不要写内容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.principle
{
    public interface Interface
    {
        void operation1();
        void operation2();
        void operation3();
        void operation4();
        void operation5();
    }
    #region 不隔离接口
    public class A : Interface
    {
        public void operation1()
        {
            Console.WriteLine("Class B Implements operation1");
        }
        public void operation2()
        {
            Console.WriteLine("Class B Implements operation2");
        }
        public void operation3()
        {
            Console.WriteLine("Class B Implements operation3");
        }
        public void operation4()
        {
            Console.WriteLine("Class B Implements operation4");
        }
        public void operation5()
        {
            Console.WriteLine("Class B Implements operation5");
        }
    }
    public class B//依赖接口A实现方法1,2,3
    {
        public void dependency1(Interface i)
        {
            i.operation1();
        }
        public void dependency2(Interface i)
        {
            i.operation2();
        }
        public void dependency3(Interface i)
        {
            i.operation3();
        }
    }
    public class C//依赖A实现方法1,3,4
    {
        public void dependency1(Interface i)
        {
            i.operation1();
        }
        public void dependency3(Interface i)
        {
            i.operation3();
        }
        public void dependency4(Interface i)
        {
            i.operation4();
        }
    }
    #endregion
    #region 接口隔离
    public interface Interface1
    {
        void operation1();
        void operation2();
        void operation3();
    }
    public interface Interface2
    {
        void operation1();
        void operation3();
        void operation4();
    }
    public class D : Interface1
    {
        public void operation1()
        {
            //
        }
        public void operation2()
        {
            //
        }
        public void operation3()
        {
            //
        }

    }
    public class E : Interface2
    {
        public void operation1()
        {
            //
        }
        public void operation3()
        {
            //
        }
        public void operation4()
        {
            //
        }
    }
    public class F//依赖D实现接口1方法
    {
        public void dependency1(Interface1 I)
        {
            I.operation1();
        }
        public void dependency2(Interface1 I)
        {
            I.operation2();
        }
        public void dependency3(Interface1 I)
        {
            I.operation3();
        }
    }
    public class G//依赖E实现接口2方法
    {
        public void dependency1(Interface2 I)
        {
            I.operation1();
        }
        public void dependency3(Interface2 I)
        {
            I.operation3();
        }
        public void dependency4(Interface2 I)
        {
            I.operation4();
        }
    }
    #endregion
}


4. 依赖倒转原则

  1. 高层依赖底层,两者依赖抽象
  2. 抽象不依赖细节
  3. 面向接口和抽象编程
  4. 底层模块都尽量要有接口或者抽象,程序稳定性好
  5. 变量的声明尽量是抽象类或者接口,实现多态
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.principle
{
    class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person();
            person.receive(new Email());
            Person1 person1 = new Person1();
            person1.receive(new Wechat());
            person1.receive(new Phone());
        }
    }
    class DependenceInversionPrinciple
    {
    }

    #region 没有接口或抽象
    public class Email
    {
        public String getinfo()
        {
            return "This is an email";
        }
    }
    public class Person
    {
        public void receive(Email email)
        {
            Console.WriteLine(email.getinfo()); 
        }
    }
    #endregion
    #region 依赖倒转
    public interface Message
    {
        String getinfo();
    }
    public class Wechat: Message
    {
        public String getinfo()
        {
            return "This is WeChat";
        }
    }
    public class Phone : Message
    {
        public String getinfo()
        {
            return "This is Phone";
        }
    }
    public class Person1
    {
        public void receive(Message message)
        {
            Console.WriteLine(message.getinfo());
        }
    }
    #endregion
}

5. 里氏替换原则

  1. 基类可以出现的地方,子类一定能出现。强调继承的时候,子类尽量不要修改父类方法;
  2. 让原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖,聚合,组合等关系替代。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.principle
{
    class Program
    {
        static void Main(string[] args)
        {
            Plus plus = new Plus();
            plus.plus(2, 5);
        }
    }
    class LiskowPrinciple
    {
    }
    public abstract class Operator
    {
        
    }
    public class BasicPlus: Operator
    {
        public String plus(int a, int b)
        {
            return (a + b).ToString();
        }
    }
    public class Plus: Operator
    {
        /// 
        /// 组合,聚类,不直接继承
        /// 
        private BasicPlus basicPlus = new BasicPlus();
        public void plus(int a, int b)
        {
            Console.WriteLine(this.basicPlus.plus(a, b));
        }
    }
}

6. 迪米特法则(最少知道原则)

  1. 一个对象对其他对象保持最少了解。
  2. 直接朋友,只要两个类之间有耦合关系,两个类就是朋友关系。当一个类在另一个类中以成员变量、方法参数或者返回值的形式出现时,这两个类叫直接朋友。当类以局部变量出现的时候,这两个类彼此叫陌生朋友,陌生类尽量不要出现。
  3. 一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立,降低类之间的耦合。

7. 合成复用原则

尽量使用合成聚合的方式而不是继承,减少耦合

  1. 依赖:一个类中只要有其他类,不管是成员、参数还是返回值或是局部变量,都是依赖关系;
  2. 聚合:依赖对象没有了以后,本对象仍然在;
  3. 组合:依赖对象和本对象同生共死。
public class Person
{
	private Head head = new Head();
	private Hand hand;
	public void cuthand()
	{
		//person can live without hand
	}
	public void cuthead()
	{
		//person cannot live without head
	}
}
public class Head
{
	//
}
public class Hand
{
	//
}

一、创建模式

1. 单例模式

类的某个成员变量为静态储存变量,外部任何访问都是访问的同一个对象。

  1. 饿汉模式:成员变量随着类的加载就完成加载了,等待外部使用,可能浪费内存;但类的加载线程安全的,所以静态成员在创建的时候就是唯一的。
  2. 懒汉模式:成员变量不随类的加载而加载,仅当外部访问的时候才开始加载(懒加载),节省内存。但是多个外部同时访问成员的时候,可能导致成员加载出多个实例,需要通过其他方法保证线程安全。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.CreateMode
{
    class Singleton
    {
        #region 饿汉式,类创建的时候也创建了instance,占内存
        private static Singleton instance = new Singleton();
        private Singleton()
        {
            //
        }
        public Singleton getinstance()
        {
            return instance;
        }
        #endregion
        
        #region 懒汉式, 适用的时候才创建对象,线程不安全,
        //只能在单线程下使用
        private static Singleton instance1;
        public Singleton getinstance1()
        {
            if (instance1 == null)
                //多线程情况下,如果有一个线程已经进来
                //但是尚未创建对象,另一个线程也进来了
                //这时候就会创建多个对象
                //因此在实际开发中,这种懒汉式不能用
                //如果要用就需要对getinstance1()方法加线程锁
                //但是加线程锁会导致该方法执行效率下降
                return instance1 = new Singleton();
            else
                return instance1;
        }
        #endregion
        
        #region 双重检查懒汉式,推荐使用
        private static Singleton instance2;
        public Singleton getinstance2()
        {
            if (instance2 == null)
            {
                //这里加线程锁,当第一个线程过来时候
                //创建对象,同时阻塞其他线程,
                //创建对象后,所有线程都不会再走这个部分,效率提高
                if (instance2 == null)
                {
                    instance2 = new Singleton();
                }
                return instance2;
            }
            else
                return instance2;
        }
        #endregion
        
        #region 静态内部类,来自Java里面的内容
        //利用的是java虚拟机装载静态内部类线程安全,同时具有延迟加载懒汉效果
        public static class INSTANCE
        {
            //jvm在初始化内的时候不会加载静态内部类
            //达到懒汉效果
            private static Singleton instance3 = new Singleton();
            public static Singleton getinstance3()
            {
                return instance3;
            }
        }
        public Singleton getinstance3()
        {
            return INSTANCE.getinstance3();
        }
        #endregion
    }
}

2、工厂模式

  1. 简单工厂—命令工厂:用户输入对应产品名称,输出对应的产品;
  2. 简单工厂—静态方法工厂:用户直接调用对应产品的方法,相比起来避免修改命令工厂的if-else
  3. 普通工厂:实现了开闭原则,增加产品和工厂都不修改源代码。
    Factory pattern is one of the most used design patterns. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
    In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

Java Demo

[设计模式|C#&Java]设计模式学习笔记_第1张图片
Step 1
Create an interface for product.
Shape:

public interface Shape {
   void draw();
}

Step 2
Create concrete classes implementation for interface
Rectangle:

public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Sqare:

public class Square implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}

Circle:

public class Circle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

Step 3
Create a factory for disfferent products when different requirements are proposed
Shape Factory:

public class ShapeFactory {
	
   //use getShape method to get object of type shape 
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }		
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
         
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
         
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      
      return null;
   }
}

Step 4
Use demo:

public class FactoryPatternDemo {

   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();

      //get an object of Circle and call its draw method.
      Shape shape1 = shapeFactory.getShape("CIRCLE");

      //call draw method of Circle
      shape1.draw();

      //get an object of Rectangle and call its draw method.
      Shape shape2 = shapeFactory.getShape("RECTANGLE");

      //call draw method of Rectangle
      shape2.draw();

      //get an object of Square and call its draw method.
      Shape shape3 = shapeFactory.getShape("SQUARE");

      //call draw method of square
      shape3.draw();
   }
}

C# Demo

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.CreateMode
{
    //创建的产品,同一类东西要建立抽象的概念
    public interface Pizza
    {
        void prepare();
        void bacon();
    }
    class OrangePizza : Pizza
    {
        public OrangePizza()
        {
            //
        }
        public void prepare()
        {
            Console.WriteLine("Prepare OrangePizza");
        }
        public void bacon()
        {
            //
        }
    }
    class StrawberryPizza : Pizza
    {
        public StrawberryPizza()
        {
            //
        }
        public void prepare()
        {
            Console.WriteLine("Prepare StrawberryPizza");
        }
        public void bacon()
        {
            //
        }
    }
    #region 简单工厂—命令工厂
    class PizzaStore
    {
        public Pizza orderpizza(String name)
        {
            Pizza pizza = null;
            if (name == "Orange pizza")
                pizza = new OrangePizza();
            else if (name == "Strawberry pizza")
                pizza = new StrawberryPizza();
            else
                Console.WriteLine("No such pizza");
            return pizza;
        }
    }
    #endregion

    #region 简单工厂—方法工厂
    class PizzaStore1
    {
        public Pizza orderorangepizza()
        {
            return new OrangePizza();
        }
        public Pizza orderstrawberrypizza()
        {
            return new OrangePizza();
        }
    }
    #endregion

    #region 普通工厂/抽象工厂
    //抽象商店
    public abstract class Store
    {
        public abstract Pizza order();
    }
    public class OrangePizzaStore: Store
    {
        public override Pizza order()
        {
            return new OrangePizza();
        }
    }
    public class StrawberryPizzaStore : Store
    {
        public override Pizza order()
        {
            return new StrawberryPizza();
        }
    }
    #endregion
}

3.抽象工厂

Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.

Java Demo

[设计模式|C#&Java]设计模式学习笔记_第2张图片
Step 1
Create an interface for Shapes
Shape:

public interface Shape {
   void draw();
}

Step 2
Create concrete classes implementation for the interface
RoundedRectangle:

public class RoundedRectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside RoundedRectangle::draw() method.");
   }
}

RoundedSquare:

public class RoundedSquare implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside RoundedSquare::draw() method.");
   }
}

Rectangle:

public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Step 3
Create an Abstract class to get factories for Normal and RoundedRectangle.
AbstractFactory:

public abstract class AbstractFactory {
   abstract Shape getShape(String shapeType) ;
}

Step 4
Create Factory classes extending AbstractFactory to generate object of concrete class based on given information.
ShapeFactory:

public class ShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }	 
      return null;
   }
}

RoundedShapeFactory:

public class RoundedShapeFactory extends AbstractFactory {
   @Override
   public Shape getShape(String shapeType){    
      if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new RoundedRectangle();         
      }else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new RoundedSquare();
      }	 
      return null;
   }
}

Step 5
Create a Factory generate class to get factories by passing an information such as Shape.
FactoryProducer:

public class FactoryProducer {
   public static AbstractFactory getFactory(boolean rounded){   
      if(rounded){
         return new RoundedShapeFactory();         
      }else{
         return new ShapeFactory();
      }
   }
}

Step 6
Use Demo

public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      //get shape factory
      AbstractFactory shapeFactory = FactoryProducer.getFactory(false);
      //get an object of Shape Rectangle
      Shape shape1 = shapeFactory.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape1.draw();
      //get an object of Shape Square 
      Shape shape2 = shapeFactory.getShape("SQUARE");
      //call draw method of Shape Square
      shape2.draw();
      //get shape factory
      AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true);
      //get an object of Shape Rectangle
      Shape shape3 = shapeFactory1.getShape("RECTANGLE");
      //call draw method of Shape Rectangle
      shape3.draw();
      //get an object of Shape Square 
      Shape shape4 = shapeFactory1.getShape("SQUARE");
      //call draw method of Shape Square
      shape4.draw();
   }
}

4、原型模式

原型模式在于实现ICloneable接口的Clone方法,进而对对象实现复制,这里只是浅拷贝,深拷贝可以用序列化自己写。在Python中可以直接用copy或deepcopy方法自己构造一个Clone方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.CreateMode
{
    public class Prototype
    {
        public static void Main(String[] args)
        {
            Sheep sheep = new Sheep("OriSheep");
            Sheep clonedSheep = sheep.Clone() as Sheep;
            Console.WriteLine(clonedSheep.getname());
        }
    }
    #region 原型模式,浅拷贝,值类型
    class Sheep : ICloneable
    {
        private string name;
        public Sheep(String name)
        {
            this.name = name;
        }
        public string getname()
        {
            return this.name;
        }
        public object Clone()//浅拷贝,浅拷贝
        {
            return new Sheep(this.name) as Sheep;
        }
    }
    #endregion
}

5、建造者模式

核心思想:把产品和产品的建造过程分开解耦。
使用范围:产品之间的差异小;
建造模式四个角色:

  1. Product(产品角色):一个具有的产品的对象;
  2. Builder(抽象产品建设者):包含创建一个Product对象所需要的各个方法的抽象接口;
  3. ConcreteBuilder(具体建造者):Builder的具体实现;
  4. Director(指挥者):构建一个使用接口的对象,主要用于创建一个复杂的对象,两个作用,一是隔离客户和对象的生产方法,二是负责控制产品的生产过程。

Builder pattern builds a complex object using simple objects and using a step by step approach. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
A Builder class builds the final object step by step. This builder is independent of other objects

Java Demo

[设计模式|C#&Java]设计模式学习笔记_第3张图片

C# Demo

[设计模式|C#&Java]设计模式学习笔记_第4张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.CreateMode
{
    class Builder//客户端
    {
        public static void Main(String [] args)
        {
            HouseDirector houseDirector = new HouseDirector();
            CommonHouseBuilder commonHouse = new CommonHouseBuilder();
            houseDirector.house = commonHouse;
            House builtHouse = houseDirector.build();
            Console.WriteLine("Baisi: "+ builtHouse.basis.ToString() + "Wall: " + builtHouse.wall.ToString() + "Roof: "+ builtHouse.roof.ToString());
        }
    }
    #region 定义产品及属性
    public class House
    {
        public int basis;
        public int wall;
        public int roof;
    }
    #endregion
    #region 抽象建造者,组合产品和抽象方法
    public abstract class HouseBuilder
    {
        public House house = new House();//组合产品
        #region 将产品和建造方法分开
        public abstract void buildbasis();
        public abstract void buildwall();
        public abstract void buildroof();
        #endregion
    }
    #endregion
    #region 具体建造者,实现建造方法
    public class CommonHouseBuilder : HouseBuilder
    {
        public override void buildbasis()
        {
            base.house.basis = 20;
        }
        public override void buildroof()
        {
            base.house.wall = 30;
        }
        public override void buildwall()
        {
            base.house.roof = 40;
        }
    }
    #endregion
    #region 建造指挥者,指定建造的产品的类型和具体建造步骤
    public class HouseDirector
    {
        public HouseBuilder house = null;//聚合
        #region 将建造步骤交给建造者来决定
        public House build()
        {
            house.buildbasis();
            house.buildwall();
            house.buildroof();
            return house.house;
        }
        #endregion
        #endregion
    }
}

二、结构模式

1、适配器模式

适配器:将一个类的接口转化为另一种接口,从用户的角度看不到被适配,是解耦的;有类适配器、对象适配器和接口适配器三种。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    class Adapter
    {
        public static void Main(string [] args)
        {
            #region 类适配器
            ClassAdapter5V adapter = new ClassAdapter5V();
            Phone phone = new Phone();
            phone.charge(adapter);
            Console.WriteLine("手机电压:" + phone.SOC.ToString() + "V");
            #endregion
            #region 对象适配器
            ObjectAdapter22V objectAdapter22V = new ObjectAdapter22V();
            Phone huawei = new Phone();
            huawei.charge(objectAdapter22V);
            Console.WriteLine("华为电压:" + huawei.SOC.ToString() + "V");
            #endregion
            #region 接口适配器
            //没搞懂
            #endregion
        }
    }
    public class OutPut220V
    {
        public int output220V()
        {
            return 220;
        }
    }
    public interface VoltageAdapter
    {
        int output();
    }
    #region 类适配器
    public class ClassAdapter5V : OutPut220V, VoltageAdapter
    {
        //采用继承
        public int output()
        {
            return output220V() / 44;
        }
    }
    #endregion

    #region 对象适配器
    public class ObjectAdapter22V : VoltageAdapter
    {
        //采用组合
        public OutPut220V output220V = new OutPut220V();
        public int output()
        {
            return output220V.output220V()/10;
        }
    }
    #endregion
    public class Phone
    {
        public int SOC;
        public void charge(VoltageAdapter output)
        {
            SOC = output.output();
        }
    }
    #region 接口适配器
    public interface Interface
    {
        void interface1();
        void interface2();
        void interface3();
    }
    public abstract class InterfaceAdapter : Interface
    {
        public abstract void interface1();
        public abstract void interface2();
        public abstract void interface3();
    }
    public class InterfaceInstance : InterfaceAdapter
    {
        public override void interface1()
        {
            // ;
        }
        public override void interface2()
        {
            //;
        }
        public override void interface3()
        {
            //;
        }
    }
    #endregion
}

2、桥接模式

基于最小设计原则,通过继承、聚合和组合让不同的的类承担不同的职责,将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。
适用范围:多重分类组合问题,分类不同但是方法相同,例如:

  1. 转账分类: 按方式分为网上转账,柜台转账,AMT转账;按用户分为普通用户,银行卡用户,VIP用户;
  2. 消息分类:按实时性分为即时消息,延时消息;按设备分为手机消息,邮件消息,QQ消息
  3. 手机分类:按品牌分类,按智能程度分类,按手机样式分类

Java Demo

Bridge is used when we need to decouple an abstraction from its implementation so that the two can vary independently. This type of design pattern comes under structural pattern as this pattern decouples implementation class and abstract class by providing a bridge structure between them.
This pattern involves an interface which acts as a bridge which makes the functionality of concrete classes independent from interface implementer classes. Both types of classes can be altered structurally without affecting each other.
[设计模式|C#&Java]设计模式学习笔记_第5张图片
Step 1
Create bridge implementer interface.
DrawAPI:

public interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

Step 2
Create concrete bridge implementer classes implementing the DrawAPI interface.
RedCircle:

public class RedCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: red, radius: " + radius + ", x: " + x + ", " + y + "]");
   }
}

GreenCircle:

public class GreenCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle[ color: green, radius: " + radius + ", x: " + x + ", " + y + "]");
   }
}

Step 3
create an abstract class Shape using the DrawingAPI interface
Shape:

public abstract class Shape {
   protected DrawAPI drawAPI;
   
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();	
}

Step 4
create concrete class implementing the Shape interface
Circle:

public class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;  
      this.y = y;  
      this.radius = radius;
   }

   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

Step 5
Use the Shape and DrawAPI classes to draw different colored circles.
BridgePatternDemo:

public class BridgePatternDemo {
   public static void main(String[] args) {
      Shape redCircle = new Circle(100,100, 10, new RedCircle());
      Shape greenCircle = new Circle(100,100, 10, new GreenCircle());
      redCircle.draw();
      greenCircle.draw();
   }
}

C# Demo

[设计模式|C#&Java]设计模式学习笔记_第6张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    class Bridge
    {
        public static void Main(string[] args)
        {
            PhonePattern phone = new FoldedPhone(new HuaWei());
            phone.call();
            phone.close();
            phone.open();
        }
    }

    public interface PhoneBrand
    {
        void open();
        void call();
        void close();
    }

    public class XiaoMi : PhoneBrand
    {
        public void call()
        {
            Console.WriteLine("小米手机打电话");
        }

        public void close()
        {
            Console.WriteLine("小米手机关机");
        }

        public void open()
        {
            Console.WriteLine("小米手机开机");
        }
    }

    public class HuaWei : PhoneBrand
    {
        public void call()
        {
            Console.WriteLine("华为手机打电话");
        }

        public void close()
        {
            Console.WriteLine("华为手机关机");
        }

        public void open()
        {
            Console.WriteLine("华为手机开机");
        }
    }

    public abstract class PhonePattern
    {
        private PhoneBrand phoneBrand;
        public PhonePattern(PhoneBrand phoneBrand)
        {
            this.phoneBrand = phoneBrand;
        }
        /// 
        /// 这里的open, close 和call就可以看成桥,通过这几个函数方法
        /// 访问PhoneBrand的对应方法
        /// 
        public void open()
        {
            this.pattern();
            this.phoneBrand.open();
        }
        public void close()
        {
            this.pattern();
            this.phoneBrand.close();
        }
        public void call()
        {
            this.pattern();
            this.phoneBrand.call();
        }
        public abstract void pattern();
    }

    public class  FoldedPhone : PhonePattern
    {
        public FoldedPhone(PhoneBrand phoneBrand) : base(phoneBrand)
        {
            //
        }

        public override void pattern()
        {
            Console.WriteLine("这是折叠手机");
        }
    }

    public class SliderPhone : PhonePattern
    {
        public SliderPhone(PhoneBrand phoneBrand) : base(phoneBrand)
        {
            //
        }

        public override void pattern()
        {
            Console.WriteLine("这是滑盖手机");
        }
    }
}

3、装饰器模式

[设计模式|C#&Java]设计模式学习笔记_第7张图片
[设计模式|C#&Java]设计模式学习笔记_第8张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    class Decorator
    {
        public static void Main(string[] args)
        {
            Additional banana = new Sugar(new StartBuck(2), 10);
            Console.WriteLine(banana.description());
            Console.WriteLine(banana.cost());
        }
    }

    #region 被装饰抽象类
    public abstract class Coffee
    {
        public string name;
        public float price;
        public int number;
        public abstract float cost();
        public abstract string description();
    }
    #endregion
    /// 
    /// 实例化被装饰的抽象类
    /// 
    public class Luckin : Coffee
    {
        public Luckin(int cups)
        {
            this.name = "瑞星咖啡";
            this.price = 10;
            this.number = cups;
        }

        public override float cost()
        {
            return this.price*this.number;
        }

        public override string description()
        {
            return this.name + " " + this.number.ToString() + "杯";
        }
    }

    public class StartBuck : Coffee
    {
        public StartBuck(int cups)
        {
            this.name = "星巴克咖啡";
            this.price = 20;
            this.number = cups;
        }

        public override float cost()
        {
            return this.price * this.number;
        }

        public override string description()
        {
            return this.name + " " + this.number.ToString() + "杯";
        }
    }

    #region 装饰器抽象类,这里对咖啡进行装饰
    public class Additional : Coffee
    {
        /// 
        /// 采用聚合方法对被装饰的类的方法进行装饰,这里和桥接模式
        /// 好像有点类似,也说不出来具体区别在哪里,桥接那里没有更改原来方法的内容
        /// 
        public Coffee coffee;
        public Additional(Coffee coffee)
        {
            this.coffee = coffee;
        }
        public override float cost()
        {
            return this.price * this.number + this.coffee.cost();
        }

        public override string description()
        {
            return this.coffee.description() + ", " + this.name + " " + this.number.ToString() + "个";
        }
    }
    #endregion
    /// 
    /// 实例化装饰器类
    /// 
    public class Banana : Additional
    {
        public Banana(Coffee coffee, int num) : base(coffee)
        {
            this.name = "Banana";
            this.price = 5;
            this.number = num;
        }
    }

    public class Sugar : Additional
    {
        public Sugar(Coffee coffee, int num) : base(coffee)
        {
            this.name = "Sugar";
            this.price = 2;
            this.number = num;
        }
    }
}

4、组合模式

可以看成树结构,根节点没有父节点,叶子节点没有子节点,其他节点都会聚合父节点和子节点,适合组织架构关系的表达与操作。
[设计模式|C#&Java]设计模式学习笔记_第9张图片

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    class Composite
    {
        public static void Main(string [] args)
        {
            Node school = new Node("吉林大学");
            Node automobile = new Node("汽车工程学院", school);
            Node material = new Node("材料学院", school);
            Node vehicle = new Node("车辆工程专业");
            Node engine = new Node("发动机专业");
            Node body = new Node("车身专业");
            school.addson(automobile);
            school.addson(material);
            automobile.addson(vehicle);
            automobile.addson(engine);
            automobile.addson(body);
            school.present();
            automobile.present();
        }
    }

    public abstract class BasicNode
    {
        public string name;
        public BasicNode fatherNode;
        public List<BasicNode> sonNodes = new List<BasicNode>();
        /// 
        /// 增加节点
        /// 
        /// 
        public abstract void addson(BasicNode node);
        /// 
        /// 更改父节点
        /// 
        /// 
        public abstract void changefather(BasicNode node);
        /// 
        /// 删除节点
        /// 
        /// 
        public abstract void remove(BasicNode node);
        /// 
        /// 显示本级节点与子节点
        /// 
        public abstract void present();
    }

    public class Node : BasicNode
    {
        /// 
        /// 根节点构造函数
        /// 
        /// 
        public Node(string name)
        {
            this.fatherNode = null;
            this.name = name;
        }

        /// 
        /// 非根节点构造函数
        /// 
        /// 
        /// 
        public Node(string name, Node fatherNode)
        {
            this.name = name;
            this.fatherNode = fatherNode;
        }

        public override void addson(BasicNode node)
        {
            this.sonNodes.Add(node);
        }

        public override void changefather(BasicNode node)
        {
            this.fatherNode = node;
        }

        public override void present()
        {
            Console.WriteLine("===== "+this.name.ToString()+" =====");
            foreach (var sonNode in this.sonNodes)
            {
                Console.WriteLine(sonNode.name.ToString());
            }
        }
        public override void remove(BasicNode node)
        {
            if (this.sonNodes.Contains(node))
            {
                this.sonNodes.Remove(node);
            }
        }
    }
}

5、外观模式

外观类:为调用端提供统一的接口,中间做一个代理;
子系统:功能的实际提供者。
作用:将多个子系统组合成一个大系统,对大系统进行分层组合,解决多个复杂接口带来的适用困难,简化用户操作,更好划分访问的层次。
本质就是当系统很复杂的时候,采用一个更高层的接口来组合适用子系统。当系统不复杂就不需要用外观模式。
[设计模式|C#&Java]设计模式学习笔记_第10张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    class Client
    {
        public static void Main(string [] args)
        {
            Facade homeTheater = new Facade();
            homeTheater.prepared();
            homeTheater.start();
            homeTheater.finish();
        }
    }

    #region 子系统
    public class DVDPlayer
    {
        private static DVDPlayer player = new DVDPlayer();
        private DVDPlayer()
        {
            //
        }
        public static DVDPlayer getinstance()
        {
            return player;
        }
        public void on()
        {
            Console.WriteLine("DVD打开");
        }
        public void off()
        {
            Console.WriteLine("DVD关闭");
        }
        public void play()
        {
            Console.WriteLine("DVD播放");
        }
    }
    public class Popcorn
    {
        private static Popcorn popcorn = new Popcorn();
        public static Popcorn getinstance()
        {
            return popcorn;
        }
        private Popcorn()
        {
            //
        }
        public void on()
        {
            Console.WriteLine("爆米花机打开");
        }
        public void off()
        {
            Console.WriteLine("爆米花机关闭");
        }
    }

    public class Screen
    {
        private static Screen screen = new Screen();
        public static Screen getinstance()
        {
            return screen;
        }
        private Screen()
        {
            //
        }
        public void on()
        {
            Console.WriteLine("屏幕打开");
        }
        public void off()
        {
            Console.WriteLine("屏幕关闭");
        }
    }
    #endregion

    #region 外观类
    public class Facade
    {
        /// 
        /// 组合子系统
        /// 
        private Screen screen;
        private DVDPlayer player;
        private Popcorn popcorn;
        public Facade()
        {
            screen = Screen.getinstance();
            player = DVDPlayer.getinstance();
            popcorn = Popcorn.getinstance();
        }
        public void prepared()
        {
            Console.WriteLine("准备看电影:");
            popcorn.on();
            screen.on();
            Console.WriteLine("=======");
        }
        public void start()
        {
            Console.WriteLine("开始看电影:");
            popcorn.off();
            player.on();
            player.play();
            Console.WriteLine("=======");
        }
        public void finish()
        {
            Console.WriteLine("电影看完:");
            player.off();
            screen.off();
            Console.WriteLine("=======");
        }
    }
    #endregion
}

6、享元模式

享元模式(蝇量模式)就是对于已经有的资源不再生成新的实例,将现有的实例返回给客户端。采用一个享元类作为缓冲层与客户端对接。
享元模式减少了对象的创建,从而降低了程序的占用内存,提高效率,但是享元模式会增加系统的复杂程度
适用享元模式要注意划分外部状态和内部状态,并且需要有一个工厂类加以控制;
享元模式的经典应用是需要缓冲的场景,比如string常量池,数据库连接池等。
[设计模式|C#&Java]设计模式学习笔记_第11张图片

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    public class Client
    {
        public static void Main(string[] args)
        {
            FlyWeight flyWeight = new FlyWeight();
            WebSite QQ = flyWeight.getwebsite("QQ");
            QQ.use(new User("QQ"));
            flyWeight.getsize();
            WebSite weChat = flyWeight.getwebsite("微信");
            weChat.use(new User("微信1"));
            flyWeight.getsize();
            WebSite weChat1 = flyWeight.getwebsite("微信");
            weChat1.use(new User("微信2"));
            flyWeight.getsize();
        }
    }
    public class User
    {
        private string name;
        public User(string name)
        {
            this.name = name;
        }
        public string Name
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
            }
        }
    }

    public abstract class WebSite
    {
        public abstract void use(User user);
    }

    public class ConcreteWebSite : WebSite
    {
        private string name = "";
        public ConcreteWebSite(string name)
        {
            this.name = name;
        }
        public override void use(User user)
        {
            Console.WriteLine("用户" + user.Name + "在使用的网站的发布形式为" + this.name);
        }
    }
    //根据需求返回一个网站
    #region 享元类,利用享元类来产生需要的网站类型
    class FlyWeight
    {
        private Hashtable pool = new Hashtable();
        public WebSite getwebsite(string name)
        {
            if (!pool.ContainsKey(name))
            {
                pool.Add(name, new ConcreteWebSite(name));
            }
            return pool[name] as WebSite;
        }
        public void getsize()
        {
            Console.WriteLine("Pool池数量为: " + pool.Count.ToString());
        }
    }
    #endregion
}

7、代理模式

代理模式(Proxy):为一个对象提供一个替身,以控制对这个对象的访问,通过代理对象访问目标对象;
有点:可以在目标对象实现的基础上增强额外的功能(这点和装饰器模式有点像);
被代理的对象可以是远程对象,创建开销大的对象或者需要安全控制的对象;
代理模式有三种:
静态代理,需要目标对象和代理对象都实现接口;
动态代理:要求目标对象实现接口,采用反射机制实现一个代理对象,
Cglib代理(Java),不需要目标对象实现接口,通过字节码处理框架ASM来转换字节码并生成新的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Structure
{
    public class Client
    {
        public static void Main(string[] args)
        {
            #region 静态代理
            StaticProxy teacher = new TeacherYang(new TeacherWang());
            Console.WriteLine(teacher.teach());
            #endregion
            #region 动态代理
            //动态代理需要用到反射机制,初学用不到,以后再高
            #endregion

        }
    }
    #region 静态代理                                                               
    public interface StaticProxy
    {
        string teach();
    }
    public class TeacherWang : StaticProxy
    {
        public string teach()
        {
            return "王老师授课";
        }
    }
    public class TeacherYang : StaticProxy
    {
        private StaticProxy teacher;
        public TeacherYang(StaticProxy teacher)
        {
            this.teacher = teacher;
        }

        public string teach()
        {
            return "杨老师代理" + this.teacher.teach();
        }
    }
    #endregion
}

三、行为模式

1、模板方法模式

在抽象类中定义一系列方法的执行顺序,但是每种方法都留给具体的实例去实现。其中可以定义一些钩子或者开关来对指定的某些方法进行开闭。

[设计模式|C#&Java]设计模式学习笔记_第12张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            Templete apple = new Apple();
            apple.templete();
            Templete banana = new Banana();
            banana.templete();
        }
    }
    public abstract class Templete
    {
        public Templete()
        {
            //
        }
        public void templete()
        {
            operation1();
            operation2();
            #region 钩子方法
            if (!removeoperation3())
            {
                operation3();
            }
            #endregion


        }
        public abstract void operation1();
        public abstract void operation2();
        public abstract void operation3();
        public abstract bool removeoperation3();
    }

    public class Apple : Templete
    {
        public Apple()
        {
            Console.WriteLine("===苹果处理方法===");
        }
        public override void operation1()
        {
            Console.WriteLine("先洗干净");
        }

        public override void operation2()
        {
            Console.WriteLine("去皮"); 
        }

        public override void operation3()
        {
            Console.WriteLine("吃掉"); ;
        }

        public override bool removeoperation3()
        {
            return false;
        }
    }
    public class Banana : Templete
    {
        public Banana()
        {
            Console.WriteLine("===香蕉处理方法===");
        }
        public override void operation1()
        {
            Console.WriteLine("去皮");
        }

        public override void operation2()
        {
            Console.WriteLine("吃掉");
        }

        public override void operation3()
        {
            Console.WriteLine("多余步骤");
        }

        public override bool removeoperation3()
        {
            return true;
        }
    }
}

2、命令模式

命令模式中,将一个请教封装成一个对象,以便不同参数来表示不同的请教,同时命令模式也要求支持撤销操作。

Java Demo

Command pattern is a data driven design pattern and falls under behavioral pattern category. A request is wrapped under an object as command and passed to invoker object. Invoker object looks for the appropriate object which can handle this command and passes the command to the corresponding object which executes the command.
[设计模式|C#&Java]设计模式学习笔记_第13张图片
Step 1
Create a command interface.
Order:

public interface Order {
   void execute();
}

Step 2
create a request class
(命令具体的完成者,由这个类来具体完成每一个指令)
Stock:

public class Stock {
	
   private String name = "ABC";
   private int quantity = 10;

   public void buy(){
      System.out.println("Stock [ Name: "+name+", 
         Quantity: " + quantity +" ] bought");
   }
   public void sell(){
      System.out.println("Stock [ Name: "+name+", 
         Quantity: " + quantity +" ] sold");
   }
}

Step 3
create concrete class implementation the Order interface.
(命令类型,其中聚合一个命令的执行者)
BuyStock:

public class BuyStock implements Order {
   private Stock abcStock;

   public BuyStock(Stock abcStock){
      this.abcStock = abcStock;
   }

   public void execute() {
      abcStock.buy();
   }
}

SellStock:

public class SellStock implements Order {
   private Stock abcStock;

   public SellStock(Stock abcStock){
      this.abcStock = abcStock;
   }

   public void execute() {
      abcStock.sell();
   }
}

Step 4
Create command invoker class
(命令的发布者,指挥者)
Broker:

import java.util.ArrayList;
import java.util.List;

   public class Broker {
   private List<Order> orderList = new ArrayList<Order>(); 

   public void takeOrder(Order order){
      orderList.add(order);		
   }

   public void placeOrders(){
   
      for (Order order : orderList) {
         order.execute();
      }
      orderList.clear();
   }
}

Step 5
Use the Broker class to take ad execute commands.
CommandPatternDemo:

public class CommandPatternDemo {
   public static void main(String[] args) {
      Stock abcStock = new Stock();

      BuyStock buyStockOrder = new BuyStock(abcStock);
      SellStock sellStockOrder = new SellStock(abcStock);

      Broker broker = new Broker();
      broker.takeOrder(buyStockOrder);
      broker.takeOrder(sellStockOrder);

      broker.placeOrders();
   }
}

C# Demo

[设计模式|C#&Java]设计模式学习笔记_第14张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Cient
    {
        public static void Main(string[] args)
        {
            LightReceiver lightReceiver = new LightReceiver();
            LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
            LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
            RemoteController remoteController = new RemoteController();
            remoteController.setcommand(0, lightOnCommand, lightOffCommand);
            remoteController.offcommand(0);
            remoteController.oncommand(0);
            remoteController.undocommand();
            remoteController.offcommand(1);
        }
    }
    public class LightReceiver
    {
        public LightReceiver()
        {
            //
        }
        public void on()
        {
            Console.WriteLine("电灯打开");
        }
        public void off()
        {
            Console.WriteLine("电灯关闭");
        }
    }
    public interface Command
    {
        /// 
        /// 命令接口
        /// 
        void execute();
        void cancel();
    }
    public class LightOnCommand : Command
    {
        public LightReceiver lightReceiver = null;
        public LightOnCommand(LightReceiver lightReceiver)
        {
            this.lightReceiver = lightReceiver;
        }
        public void cancel()
        {
            lightReceiver.off();
        }

        public void execute()
        {
            lightReceiver.on();
        }
    }
    public class LightOffCommand : Command
    {
        public LightReceiver lightReceiver = null;
        public LightOffCommand(LightReceiver lightReceiver)
        {
            this.lightReceiver = lightReceiver;
        }
        public void cancel()
        {
            lightReceiver.on();
        }

        public void execute()
        {
            lightReceiver.off();
        }
    }
    public class NoCommand : Command
    {
        /// 
        /// 控制性,用于初始化;当调用空命令时,对象什么都不做;
        /// 可以省掉对空的判断
        /// 
        /// 
        public NoCommand()
        {
            //
        }
        public void cancel()
        {
            //;
        }

        public void execute()
        {
            //;
        }
    }
    public  class RemoteController
    {
        private Command [] onCommandList= new Command[5];
        private Command[] offCommandList = new Command[5];
        private Command undoCommand;
        public RemoteController()
        {
            for (int i=0; i < 5; i++)
            {
                onCommandList[i] = new NoCommand();
                offCommandList[i] = new NoCommand();
            }
        }
        public void setcommand(int id, Command onCommand, Command offCommand)
        {
            onCommandList[id] = onCommand;
            offCommandList[id] = offCommand;
        }
        public void oncommand(int id)
        {
            onCommandList[id].execute();
            undoCommand = onCommandList[id];
        }
        public void offcommand(int id)
        {
            offCommandList[id].execute();
            undoCommand = offCommandList[id];
        }
        public void undocommand()
        {
            undoCommand.cancel();
        }
    }
}

3、访问者模式

优点:访问者模式服从单一原则,让程序扩展性好,灵活性高;可以做报表、拦截器、过滤器,适用于数据结构相对稳定的系统但功能经常变化。
缺点:违背了依赖倒转原则,访问者依赖的是具体的元素而不是抽象元素。

Java Demo

In Visitor pattern, a visitor class is used which changes the executing algorithm of an element class. By this way, execution algorithm of element can vary as and when visitor varies. This pattern comes under behavior pattern category. As per the pattern, element object has to accept the visitor object so that visitor object handles the operation on the element object.
访问者模式中,定义一个访问者的类,用来更改和执行一个元素类的算法。通过这种方法,当访问者更改的时候,元素类的算法也就发生了变化。
[设计模式|C#&Java]设计模式学习笔记_第15张图片
Step1
Define an interface to represent element

public interface ComputerPart {
   public void accept(ComputerPartVisitor computerPartVisitor);
}

Step2
Create concrete classes extending the above class.
keybord:

public class Keyboard implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Monitor:

public class Monitor implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Mouse:

public class Mouse implements ComputerPart {

   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Compuer:

public class Computer implements ComputerPart {
	
   ComputerPart[] parts;

   public Computer(){
      parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};		
   } 


   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      for (int i = 0; i < parts.length; i++) {
         parts[i].accept(computerPartVisitor);
      }
      computerPartVisitor.visit(this);
   }
}

Step3
Define an interface to represent visitor.
ComputerPartVisitor:

public interface ComputerPartVisitor {
	public void visit(Computer computer);
	public void visit(Mouse mouse);
	public void visit(Keyboard keyboard);
	public void visit(Monitor monitor);
}

Step4
Create concrete visitor implementing the above class.
ComputerPartDisplay:

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {

   @Override
   public void visit(Computer computer) {
      System.out.println("Displaying Computer.");
   }

   @Override
   public void visit(Mouse mouse) {
      System.out.println("Displaying Mouse.");
   }

   @Override
   public void visit(Keyboard keyboard) {
      System.out.println("Displaying Keyboard.");
   }

   @Override
   public void visit(Monitor monitor) {
      System.out.println("Displaying Monitor.");
   }

Step5
Use the ComputerPartDisplayVisitor to display parts of Computer.
VisitorPatternDisplay:

public class VisitorPatternDemo {
   public static void main(String[] args) {

      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

C# Demo

[设计模式|C#&Java]设计模式学习笔记_第16张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    class Client
    {
        public static void Main()
        {
            Console.WriteLine("===========");
            Decision decision = new Success(new Man("张宇"));
            Singer Mao = new ManSinger("毛不易", decision);
            Mao.result();
            Console.WriteLine("===========");
            Decision decision1 = new Fail(new Woman("周笔畅"));
            Singer Xu = new WomanSinger("徐佳莹", decision1);
            Xu.result();
        }
    }
    #region 投票结果类
    public abstract class Decision
    {
        /// 
        /// 聚合评委
        /// 
        public Audience audience;
        public Decision(Audience audience)
        {
            this.audience = audience;
        }
        public abstract string result();
    }
    public class Success : Decision
    {
        public Success(Audience audience):base(audience)
        {
            //
        }
        public override string result()
        {
            return base.audience.getgender() + base.audience.getname() + "投票晋级";
        }
    }
    public class Fail : Decision
    {
        public Fail(Audience audience) : base(audience)
        {
            //
        }
        public override string result()
        {
            return base.audience.getgender() + base.audience.getname() + "投票淘汰";
        }
    }
    #endregion
    #region 观众评委类
    public class Audience
    {
        public string gender;
        public string name;
        public Audience(string name)
        {
            this.name = name;
        }
        public virtual string getgender(){ return gender; }
        public virtual string getname() { return name; }
    }
    public class Man : Audience
    {
        public Man(string name):base(name)
        {
            base.name = name;
            base.gender = "男评委";
        }
    }
    public class Woman : Audience
    {
        public Woman(string name):base(name)
        {
            base.name = name;
            base.gender = "女评委";
        }
    }
    #endregion
    #region 歌手类
    public abstract class Singer
    {
        /// 
        /// 聚合投票结果
        /// 
        public string name;
        public Decision decision;
        public Singer(string name, Decision decision)
        {
            this.decision = decision;
            this.name = name;
        }
        public abstract void result();
    }
    public class ManSinger : Singer
    {
        public ManSinger(string name, Decision decision) : base(name, decision)
        {
            //
        }
        public override void result()
        {
            Console.WriteLine("男歌手"+base.name +":"+base.decision.result());
        }
    }
    public class WomanSinger : Singer
    {
        public WomanSinger(string name, Decision decision) : base(name, decision)
        {
            //
        }
        public override void result()
        {
            Console.WriteLine("女歌手" + base.name + ":" + base.decision.result());
        }
    }
    #endregion
}

4、迭代器模式

提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表达,不暴露内部结构。

[设计模式|C#&Java]设计模式学习笔记_第17张图片
示例代码实现组合模式里面的大学学院和专业显示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            University university = new University("吉林大学");
            College Computer = new ComputerCollege();
            College Communication = new CommunicationCollege();
            university.addcollege(Computer);
            university.addcollege(Communication);
            university.printcollege();
        }
    }
    #region 系专业类
    public class Department
    {
        private string name;
        public Department(string name)
        {
            this.name = name;
        }
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }
    }
    #endregion
    #region 迭代器接口
    public interface Iterator
    {
        bool hasnext();
        Department next();
    }
    #endregion
    #region 迭代器具体实现
    public class ComputerCollegeIterator : Iterator
    {
        /// 
        /// 计算机学院的系专业按照数组的方式存储
        /// 因此相关的迭代器就是要处理一个数组
        /// 
        private Department[] department;
        private int index = 0;
        public ComputerCollegeIterator(Department[] department)
        {
            this.department = department;
        }
        public bool hasnext()
        {
            if (this.index>this.department.Length || this.department[index] == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public Department next()
        {
            Department department = this.department[index];
            index += 1;
            return department;
        }
    }

    public class ComminicationCollegeIterator : Iterator
    {
        /// 
        /// 通信学院的系专业按照序列存储
        /// 因此相应的迭代器要处理一个序列
        /// 
        List<Department> department;
        int index = 0;
        public ComminicationCollegeIterator(List<Department> department)
        {
            this.department = department;
        }
        public bool hasnext()
        {
            if (this.index > this.department.Count -1 || this.department[index]==null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public Department next()
        {
            Department department = this.department[index];
            index += 1;
            return department;
            
        }
    }
    #endregion
    #region 定义学院抽象类和实现
    public interface College
    {
        /// 
        /// 学院要有一个返回自身对应的迭代器方法
        /// 
        /// 
        string getname();
        void adddepartment(string name);
        Iterator createIterator();
    }
    public class ComputerCollege : College
    {
        /// 
        /// 数组和上述的迭代器要对应
        /// 
        public Department[] department;
        public int index = 0;
        public ComputerCollege()
        {
            this.department = new Department[5];
            this.adddepartment("网络架构");
            this.adddepartment("网络安全");
            this.adddepartment("后端设计");
            this.adddepartment("前端设计");
        }
        public void adddepartment(string name)
        {
            department[index] = new Department(name);
            index += 1;
        }

        public Iterator createIterator()
        {
            return new ComputerCollegeIterator(department);
        }

        public string getname()
        {
            return "计算机学院";
        }
    }

    public class CommunicationCollege : College
    {
        /// 
        /// 列表和上述的迭代器对应
        /// 
        public List<Department> departments;
        public CommunicationCollege()
        {
            departments = new List<Department>();
            adddepartment("鲁棒控制");
            adddepartment("现代控制");
            adddepartment("经典控制");
        }
        public void adddepartment(string name)
        {
            departments.Add(new Department(name));
        }

        public Iterator createIterator()
        {
            return new ComminicationCollegeIterator(departments);
        }

        public string getname()
        {
            return "通信学院";
        }
    }
    #endregion
    #region 大学
    public class University
    {
        private string name;
        public List<College> university;
        public University(string name)
        {
            this.name = name;
            university = new List<College>();
        }
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }
        public void addcollege(College college)
        {
            university.Add(college);
        }
        /// 
        /// 这里用了一下foreach作为对比
        /// 
        public void printcollege()
        {
            //首先遍历学院
            foreach (var college in university)
            {
                Console.WriteLine("===" + college.getname() + "===");
                //然后对指定的学院采用自身的迭代器遍历专业
                printdepartment(college.createIterator());
            }
        }
        private void printdepartment(Iterator iterator)
        {
            while (iterator.hasnext())
            {
                Console.WriteLine(iterator.next().Name);
            }
        }
    }
    #endregion
}

5、观测者模式

两种方式,一是观察者时刻盯着发布者,当发布者有更新的时候,观察者跟着变化;二是发布者自己更新后主动通知观察者进行变化。
在C#中有“订阅发布模式”,意思是差不多的,将观察者放到发布者的一个容器里面,当发布者需要告知观察者时就会去容器里面找到发布者,采用的是“事件”和“委托”的方式,本质就是函数指针,C#提供一个Action的泛型委托。
在Qt或者PyQt中,有“信号”和“槽”的机制,也是一种观察者模式。
[设计模式|C#&Java]设计模式学习笔记_第18张图片

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            Observer sina = new Sina();
            Observer tencent = new Tencent();
            CenterStation station = new WhetherStation();
            station.register(sina);
            station.setdata(10, 30);
            station.remove("新浪");
            station.register(tencent);
            station.setdata(90, 23);
        }
    }
    #region 信息发布者
    public interface CenterStation
    {
        void register(Observer observer);
        void remove(string name);
        void notify();
        void setdata(float temp, float press);
    }
    public class WhetherStation : CenterStation
    {
        private float temperature;
        private float pressure;
        //用于存放所有的观察者
        private Hashtable observers;
        public WhetherStation()
        {
            this.observers = new Hashtable();
        }
        /// 
        /// 只要有数据就发布给观察者更新
        /// 
        /// 
        /// 
        public void setdata(float temp, float press)
        {
            temperature = temp;
            pressure = press;
            Console.WriteLine("====更新数据====");
            notify();
        }
        /// 
        /// 遍历观察者发布信息
        /// 
        public void notify()
        {
            foreach (Observer observer in observers.Values)
            {
                observer.update(temperature, pressure);
                Console.WriteLine("===========");
            }
        }
        //等级注册观察者
        public void register(Observer observer)
        {
            observers.Add(observer.getname(), observer);
        }
        //移除观察者
        public void remove(string name)
        {
            if (observers.Contains(name))
            {
                observers.Remove(name);
            }
            else { Console.WriteLine("没有观察者" + name); }
        }
    }
    #endregion

    #region 观察者
    public interface Observer
    {
        void update(float temperature, float pressure);
        string getname();
    }
    public class Sina : Observer
    {
        public string getname()
        {
            return "新浪";
        }

        public void update(float temperature, float pressure)
        {
            Console.WriteLine("新浪天气提醒您:");
            Console.WriteLine("当前温度是:" + temperature.ToString()+"\n" + "当前气压是:" + pressure.ToString()); ;
        }
    }
    public class Tencent : Observer
    {
        public string getname()
        {
            return "腾讯";
        }

        public void update(float temperature, float pressure)
        {
            Console.WriteLine("腾讯天气提醒您:");
            Console.WriteLine("当前温度是:" + temperature.ToString() + "\n" + "当前气压是:" + pressure.ToString()); ;
        }
    }
    #endregion
}

6、中介模式

和外观模式有点相似,就是用一个类来集中管理很多子系统的组合,但是外观模式中用户是直接调用外观类,即上层接口;中介模式中,还有可能直接和子系统交互,一个子系统变化通过中介模式作用到其他子系统,子系统之间不直接交互都是通过中介来传递信息。
优点:多个类互相耦合的时候,通过中介将网状结构变成星型结构解耦,减少类之间的依赖,符合迪米特法则
缺点:一旦中介出问题,整个结构崩溃,当子系统很多且耦合厉害的时候,中介模式会很复杂。

[设计模式|C#&Java]设计模式学习笔记_第19张图片

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            Mediator mediator = new ConcreteMediator();
            Equipment tv = new Television(mediator);
            Equipment sofa = new Sofa(mediator);
            tv.sendstartmessage();
        }
    }
    public interface Equipment
    {
        void sendstopmessage();
        void sendstartmessage();
        void getstartmessage();
        void getstopmessage();
        Mediator getmediator();
    }
    public class Television : Equipment
    {
        private Mediator mediator;
        public string name;
        public Television(Mediator mediator)
        {
            this.name = "电视";
            this.mediator = mediator;
            this.mediator.register(name, this);
        }
        public Mediator getmediator()
        {
            return mediator;
        }
        public void sendstartmessage()
        {
            Console.WriteLine("电视机启动");
            this.mediator.getmessage(name, 1);
        }

        public void getstartmessage()
        {
            Console.WriteLine("电视开始工作");
        }

        public void getstopmessage()
        {
            Console.WriteLine("电视停止工作");
        }

        public void sendstopmessage()
        {
            Console.WriteLine("电视机关闭");
            this.mediator.getmessage(name, 0);
        }
    }

    public class Sofa : Equipment
    {
        private Mediator mediator;
        public string name;
        public Sofa(Mediator mediator)
        {
            this.name = "沙发";
            this.mediator = mediator;
            this.mediator.register(name, this);
        }
        public Mediator getmediator()
        {
            return mediator;
        }
        public void sendstartmessage()
        {
            Console.WriteLine("沙发启动");
            this.mediator.getmessage(name, 0);
        }

        public void getstartmessage()
        {
            Console.WriteLine("沙发开始工作");
        }

        public void getstopmessage()
        {
            Console.WriteLine("沙发停止工作");
        }

        public void sendstopmessage()
        {
            Console.WriteLine("沙发关闭");
            this.mediator.getmessage(name, 1);
        }
    }

    public interface Mediator
    {
        void register(string name, Equipment equipment);
        void getmessage(string name, int message);
    }
    public class ConcreteMediator : Mediator
    {
        private Hashtable equipments = new Hashtable();
        /// 
        /// 在getmessage里面通过调用Hashtable协调各个设备的工作
        /// 中介者的核心方法,这里写个示例
        /// 
        /// 
        public void getmessage(string name, int message)
        {
            if(message == 0 && name == "电视")
            {
                Equipment equipment = equipments["沙发"] as Equipment;
                equipment.getstartmessage();
            }
            else
            {
                Equipment equipment = equipments["沙发"] as Equipment;
                equipment.getstopmessage();
            }
        }

        public void register(string name, Equipment equipment)
        {
            equipments.Add(name, equipment);
        }
    }
}

7、备忘录模式

备忘就是备份保存当前类的状态。给用户提供一种恢复历史状态的机制;
缺点:如果类的成员变量过多,势必会占用较多的内存;
适用场景:后悔药,游戏存档,ctrl+z,浏览器后退等功能;
为了节约内存,备忘录模式可以和原型模式配合适用。
[设计模式|C#&Java]设计模式学习笔记_第20张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public  class Client
    {
        public static void Main(string [] args)
        {
            GameRole hero = new GameRole("德玛", 0);
            hero.printstate();
            hero.savestate();
            hero.Name = "酒桶";
            hero.Money = 50;
            hero.savestate();
            hero.printstate();
            hero.recover(0);
            hero.printstate();
        }
    }
    public class Memento
    {
        private int money;
        private string name;
        public Memento(string name, int money)
        {
            this.money = money;
            this.name = name;
        }
        public string Name
        {
            get { return this.name; }
        }
        public int Money
        {
            get { return this.money; }
        }
    }
    public class GameRole
    {
        private int money;
        private string name;
        private List<Memento> mementos;
        public GameRole(string name, int money)
        {
            this.money = money;
            this.name = name;
            mementos = new List<Memento>();
        }
        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }
        public int Money
        {
            set { this.money = value; }
            get { return this.money; }
        }
        public void savestate()
        {
            mementos.Add(new Memento(name, money));
        }
        public void recover(int index)
        {
            if (!(index > mementos.Count))
            {
                this.name = mementos[index].Name;
                this.money = mementos[index].Money;
            }
        }
        public void printstate()
        {
            Console.WriteLine("===========");
            Console.WriteLine("当前昵称是:" + name.ToString());
            Console.WriteLine("当前金币有:" + money.ToString() + " 元");
        }
    }
}

8、解释器模式

优点:

  1. 易于改变和扩展文法,由于在解释器模式中使用类表示语言的文法规则,因此可以通过继承等机制来改变和扩张文法。
  2. 每一条文法规则都可以表示为一个类,因此可以方便地实现每一个简单的语言。
  3. 实现文法比较容易。

缺点:

  1. 对于复杂文法难以维护,再解释模式下每一条规则至少定义一个类,因此如果太复杂无法处理。
  2. 执行效率低,由于大量使用了循环和递归。因此再解释很复杂的句子时速度很慢
    使用场景:

可以将一个需要解释执行的语言中的句子表示为一个抽象树。
一些重复出现的问题可以用简单的语言进行表达。
执行效率不是关键问题。

感觉这个模式有点难,没有完全理解到精髓,只做一个小例子。

Java Demo

Interpreter pattern provides a way to evaluate language grammar or expression. This type of pattern comes under behavioral pattern. This pattern involves implementing an expression interface which tells to interpret a particular context. This pattern is used in SQL parsing, symbol processing engine etc.
[设计模式|C#&Java]设计模式学习笔记_第21张图片
Step 1
create an expression interface
Expression:

public interface Expression {
   public boolean interpret(String context);
}

Step 2
Create concrete classes implementation the above interface.
TerminalExpression:

public class TerminalExpression implements Expression {
   private String data;
   public TerminalExpression(String data){
      this.data = data; 
   }

   @Override
   public boolean interpret(String context) {
   
      if(context.contains(data)){
         return true;
      }
      return false;
   }
}

OrExpression:

public class OrExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public OrExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) || expr2.interpret(context);
   }
}

AndExpression:

public class AndExpression implements Expression {
	 
   private Expression expr1 = null;
   private Expression expr2 = null;

   public AndExpression(Expression expr1, Expression expr2) { 
      this.expr1 = expr1;
      this.expr2 = expr2;
   }

   @Override
   public boolean interpret(String context) {		
      return expr1.interpret(context) && expr2.interpret(context);
   }
}

Step 3
InterpreterPatternDemo uses Expression class to create rules and then parse them.
InterpretePatternDemo:

public class InterpreterPatternDemo {

   //Rule: Robert and John are male
   public static Expression getMaleExpression(){
      Expression robert = new TerminalExpression("Robert");
      Expression john = new TerminalExpression("John");
      return new OrExpression(robert, john);		
   }

   //Rule: Julie is a married women
   public static Expression getMarriedWomanExpression(){
      Expression julie = new TerminalExpression("Julie");
      Expression married = new TerminalExpression("Married");
      return new AndExpression(julie, married);		
   }

   public static void main(String[] args) {
      Expression isMale = getMaleExpression();
      Expression isMarriedWoman = getMarriedWomanExpression();

      System.out.println("John is male? " + isMale.interpret("John"));
      System.out.println("Julie is a married women? " + isMarriedWoman.interpret("Married Julie"));
   }
}

9、状态模式

In State pattern a class behavior changes based on its state. This type of design pattern comes under behavior pattern.

In State pattern, we create objects which represent various states and a context object whose behavior varies as its state object changes.
状态模式中,需要创建刻画不同状态的对象以及一个记录当前状态的对象。

Java Demo

[设计模式|C#&Java]设计模式学习笔记_第22张图片
Step 1
Create an interface.
Stat:

public interface State {
   public void doAction(Context context);
}

Step 2
Create concrete classes implementation the same interface
StartState:

public class StartState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);	
   }

   public String toString(){
      return "Start State";
   }
}

StopState:

public class StopState implements State {

   public void doAction(Context context) {
      System.out.println("Player is in stop state");
      context.setState(this);	
   }

   public String toString(){
      return "Stop State";
   }
}

Step 3
Create Context Class
Context:

public class Context {
   private State state;

   public Context(){
      state = null;
   }

   public void setState(State state){
      this.state = state;		
   }

   public State getState(){
      return state;
   }
}

Step 4
StatPatternDemo:

public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      StartState startState = new StartState();
      startState.doAction(context);

      System.out.println(context.getState().toString());

      StopState stopState = new StopState();
      stopState.doAction(context);

      System.out.println(context.getState().toString());
   }
}

[设计模式|C#&Java]设计模式学习笔记_第23张图片

10、策略模式

  1. 把变化的代码从不变的代码中分离出来;
  2. 针对接口编程而不是针对具体的类,定义策略接口
  3. 多使用组合、聚合,少用继承。
  4. 当策略过多,类管理会比较麻烦。

[设计模式|C#&Java]设计模式学习笔记_第24张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            Duck wildDuck = new WildDuck();
            Duck homeDuck = new HomeDuck();
            wildDuck.fly();
            homeDuck.fly();
        }
    }
    public class Duck
    {
        public virtual void fly()
        {
            Console.WriteLine("鸭子会飞");
        }
        public void swim()
        {
            Console.WriteLine("鸭子会游泳");
        }
    }
    public interface FlyStrategy
    {
        void fly();
    }
    public class GoodFly : FlyStrategy
    {
        public void fly()
        {
            Console.WriteLine("飞行能力很强"); ;
        }
    }
    public class BadFly : FlyStrategy
    {
        public void fly()
        {
            Console.WriteLine("飞行能力很差"); ;
        }
    }
    public class WildDuck : Duck
    {
        private FlyStrategy flyability = new GoodFly();

        public WildDuck()
        {
            //
        }

        public override void fly()
        {
            Console.WriteLine("野鸭子");
            this.flyability.fly();
        }
    }
    public class HomeDuck : Duck
    {
        private FlyStrategy fltability = new BadFly();

        public HomeDuck()
        {
            //
        }

        public override void fly()
        {
            Console.WriteLine("家鸭子");
            this.fltability.fly();
        }
    }
}

11、职责链模式

Handler:抽象的处理者,定义了一个处理请求的接口,同时聚合一个Handler;
ConcreteHandler:实例化的处理者,如果能处理就自己请求,如果不能就交给下一级的处理者;
Request:请求指令。

[设计模式|C#&Java]设计模式学习笔记_第25张图片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignMode.Behaviour
{
    public class Client
    {
        public static void Main(string [] args)
        {
            Request request0 = new Request(500);
            Request request1 = new Request(1500);
            Request request2 = new Request(2500);
            Handler1 handler1 = new Handler1("校长", null);
            Handler handler0 = new Handler0("主任", handler1);
            handler0.processrequest(request0);
            handler0.processrequest(request1);
            handler0.processrequest(request2);
        }
    }
    public class Request
    {
        private int price;

        public Request(int price)
        {
            this.price = price;
        }

        public int Price
        { get => price; set => price = value; }
    }
    public abstract class Handler
    {
        private Handler nextHandler;
        private string name;

        public Handler(string name, Handler nextHandler)
        {
            this.nextHandler = nextHandler;
            this.name = name;
        }

        public Handler NextHandler { get => nextHandler; set => nextHandler = value; }
        public string Name { get => name; set => name = value; }

        public abstract void processrequest(Request request);
    }
    public class Handler0 : Handler
    {
        public Handler0(string name, Handler nextHandler) : base(name, nextHandler)
        {
            //
        }
        /// 
        /// Handler0处理价格在0-1000的请求;
        /// 
        /// 
        public override void processrequest(Request request)
        {
            if (0 <request.Price && request.Price < 1000)
            {
                Console.WriteLine("请求金额"+ request.Price.ToString()+"元由"+this.Name + "处理完毕");
            }
            else
            {
                this.NextHandler.processrequest(request);
            }
        }
    }
    public class Handler1 : Handler
    {
        public Handler1(string name, Handler nextHandler) : base(name, nextHandler)
        {
            //
        }
        /// 
        /// Handler1处理价格在1001-2000的请求;
        /// 
        /// 
        public override void processrequest(Request request)
        {
            if (1000 < request.Price && request.Price < 2000)
            {
                Console.WriteLine("请求金额" + request.Price.ToString() + "元由" + this.Name + "处理完毕");
            }
            else
            {
                Console.WriteLine("请求金额" + request.Price.ToString() + "元" + "超出最大限额");
            }
        }
    }
}

你可能感兴趣的:(设计模式,C#,设计模式,interface,多态,抽象类,接口)