zoukankan      html  css  js  c++  java
  • 设计模式学习笔记(1)

    前言
    以前粗略的看过设计模式,有的看懂了,有的没看懂,有的看懂了又忘了,有的在写程序时已不知不觉在用了.
    总之,现在从头学习一遍,并且开始做笔记,这样记的牢。
    以后写程序也要有意识的向设计模式靠拢。
    那本经典的《设计模式》准备去买一本,一共有23种设计模式,这里我先研究了5种,后面争取都研究完,例子是C#的,不过对于C++、java、delphi应该都是适用的。
    欢迎大家和我讨论!

    目录
    1.singleton
    2.strategy
    3.Decorator
    4.composite
    5.state

    1.Singleton
    说明:保证类只有一个实例。
    实例:
    using System;
    class Singleton
    {
     private static Singleton singleton = null;
     public static Singleton Instance()
     {
      if (null == singleton)
      singleton = new Singleton();
      return singleton;
     }

     private Singleton()
     {
     }
    }

    class Application
    {
     public static void Main()
     {
      Singleton s1 = Singleton.Instance();
      //Singleton s2 = new Singleton(); //错误:构造器不可访问
      Singleton s2 = Singleton.Instance();
      if (s1.Equals(s2)) // 引用相等
      Console.WriteLine("Instances are identical");
     }
    }

    /*以下是程序输出结果:
    Instances are identical
    */


    2.strategy
    说明:利用接口实现方法无关化,客户程序同特定算法实现细节毫无耦合关系。
    实例:
    using System;

    namespace strategy1
    {
     /// <summary>
     /// Summary description for Class.
     /// </summary>
     interface Strategy
     {
      bool IsPrime(int n);
     }

     class Miller : Strategy
     {
      public bool IsPrime(int n){
       bool result = false;
       //使用Miller法测试n是否为素数,果真,则更新result值
       Console.WriteLine("Using Miller's algorithm");
       return result;
      }
     }

     class Fermat : Strategy
     {
      public bool IsPrime(int n){
       bool result = false;
       //使用Fermat法测试n是否为素数,果真,则更新result值
       Console.WriteLine("Using Fermat's algorithm");
       return result;
      }
     }

     class Mersenne : Strategy
     {
      public bool IsPrime(int n)
      {
       bool result = false;
       //使用Mersenne法测试n是否为素数,果真,则更新result值
       Console.WriteLine("Using Mersenne's algorithm");
       return result;
      }
     }

     class Primality
     {
      private Strategy strategy;

      public Primality(Strategy s)
      {
       strategy = s;
      }
      public bool Test(int n)
      {
       return strategy.IsPrime(n);
      }
     }

     class Class
     {
      [STAThread]
      static void Main(string[] args)
      {
       Console.Write("Number to be tested: ");
       string input = Console.ReadLine();
       int n = Int32.Parse(input);
       Console.Write("Desired algorithm performance: lo, medium, hi? ");
       input = Console.ReadLine();
       char ch = char.Parse(input);
       Primality prime = null;
       switch (ch)
       {
        case 'l':
        case 'L':
        prime = new Primality(new Miller());
        break;

        case 'm':
        case 'M':
        prime = new Primality(new Fermat());
        break;

        case 'h':
        case 'H':
        prime = new Primality(new Mersenne());
        break;
       }

       if (prime != null)
       {
        bool result = prime.Test(n);
       }
       else
        Console.WriteLine("Bad Choice!");

       Console.ReadLine();
      }

     }

    }

    /*以下是某次测试输出结果:
    Number to be tested:1
    Desired algorithm performance: lo, medium, hi? M
    Using Fermat's algorithm
    */


    3.Decorator
    说明:通过子类实现功能的灵活扩展。
    实例:
    using System;

    namespace decortation
    {
     /// <summary>
     /// Summary description for Class.
     /// </summary>

    class FileTransfer
    {
     public virtual void Download(string url, byte[] data, int size)
     {
     // 下载文件
     }
     public virtual void Upload(string url, byte[] data, int size)
     {
     // 上传文件
     }
    }

    class Decorator : FileTransfer
    {
     private FileTransfer ft = new FileTransfer();
     private bool IsAccessAllowed(string url)
     {
      bool result = true;
      // 决定是否对请求的URL访问授权
      return result;
     }

     private void LogAccess(string url)
     {
      // 将URL、时间、用户身份等信息写入数据库
      Console.WriteLine("Logging access to {0}", url);
     }

     public override void Download(string url, byte[] data, int size)
     {
      if (!IsAccessAllowed(url)) return;
      ft.Download(url, data, size);
      LogAccess(url);
     }

     public override void Upload(string url, byte[] data, int size)
     {
      if (!IsAccessAllowed(url)) return;
      ft.Upload(url, data, size);
      LogAccess(url);
     }
    }


    class Class
    {
     public static void Main()
     {
      Console.Write("Enter URL to access: ");
      string url = Console.ReadLine();
      Console.Write("Enable logging and access check? ");
      string input = Console.ReadLine();
      char ch = char.Parse(input);
      bool decoration = (ch == 'y' || ch == 'Y');
      FileTransfer ft = null;
      if (!decoration)
       ft = new FileTransfer();
      else
       ft = new Decorator();
      byte[] buf = new byte[1024];
      ft.Download(url, buf, 1024);
     }
    }

    }

    4.composite
    说明:利用接口达到用一致的方式来访问所有对象(这个很常用的)。
    实例:
    C#示例:
    using System;
    using System.Collections;
    interface Shape
    {
    void Draw();
    }
    class Line : Shape
    {
    private double x1, y1, x2, y2;
    public Line(double x1, double y1, double x2, double y2)
    {
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    }
    public void Draw()
    {
    //从(x1, y1) 到(x2, y2)画一条线
    Console.WriteLine("Drawing a line");
    }
    }
    class Circle : Shape
    {
    private double x, y, r;
    public Circle(double x, double y, double radius)
    {
    this.x = x;
    this.y = y;
    this.r = r;
    }
    public void Draw()
    {
    //以(x, y)为圆心,r为半径画一个圆
    Console.WriteLine("Drawing a circle");
    }
    }
    class Drawing : Shape
    {
    private ArrayList shapes;
    public Drawing()
    {
    shapes = new ArrayList();
    }
    public void Add(Shape s)
    {
    shapes.Add(s);
    }
    public void Draw()
    {
    IEnumerator enumerator = shapes.GetEnumerator();
    while (enumerator.MoveNext())
    ((Shape) enumerator.Current).Draw();
    }
    }
    class Application
    {
    public static void Main()
    {
    Shape[] array = new Shape[3];
    array[0] = new Line(0, 0, 10, 12);
    array[1] = new Circle(2, 3, 5.5);
    Drawing dwg = new Drawing();
    dwg.Add(new Line(3, 4, 3, 5));
    dwg.Add(new Circle(5, 6, 7.7));
    array[2] = dwg;
    // 画出所有的图形,注意:用一致的方式来访问所有对象
    for (int i = 0; i < 3; ++i)
    array[i].Draw();
    }
    }
    /*以下是程序输出结果:
    Drawing a line
    Drawing a circle
    Drawing a line
    Drawing a circle
    */

    5.state
    说明:当对象内部状态改变时自动改变它的行为。

    实例:
    这个实例比较长,我简单说明一下,这是一个自动售货机的例子,客户可以投掷面值5、10、25的硬币,货物价值25。每当客户投了硬币就打印投的钱数和,如果够了25,就提示货物售出。
    state是个抽象类,它派生了5、10、15、20、25几种钱数和的类(也就是所有可能的钱数和),由于它们都是从STATE继承的,所以它们都有一个STATE类型的静态成员state作为状态的标识(你可以把它想象成全局变量),每个类都接收投入5、10、25面值的硬币,对应的方法是
    public virtual void AddNickel(VendingMachine vm) { }
    public virtual void AddDime(VendingMachine vm) { }
    public virtual void AddQuarter(VendingMachine vm) { }
    虽然方法一样,但是每个类内部实现的状态跃迁是不一样的,比如5元的类,接收10元后state就跃迁到了15元,以此类推。
    仔细看看吧,这是一个非常有意思的实例。不过说实话,这样实现程序确实太累了,也许在别的应用中可以降低程序员的负担,不过我还没发现(有的话告诉我)。
    另外如果有100种状态,有10种路径,难道每个状态都要继承(100×10)?那coding起来岂不是太累,而且代码不要太长啊,唉,当程序员真不容易啊...


    using System;

    abstract class State

    {

    public virtual void AddNickel(VendingMachine vm) { }

    public virtual void AddDime(VendingMachine vm) { }

    public virtual void AddQuarter(VendingMachine vm) { }

    protected virtual void ChangeState(VendingMachine vm, State s)

    {

    vm.ChangeState(s);

    }

    }

    class VendingMachine

    {

    private State state;

    public VendingMachine()

    {

    Console.WriteLine("The Vending Machine is now online: product costs 25c");

    state = Start.Instance();

    }

    public void ChangeState(State to)

    {

    state = to;

    }

    public void Vend()

    {

    // 发饮料

    Console.WriteLine("Dispensing product...Thank you!");

    }

    public void AddNickel()

    {

    state.AddNickel(this);

    }

    public void AddDime()

    {

    state.AddDime(this);

    }

    public void AddQuarter()

    {

    state.AddQuarter(this);

    }

    }

    class Start : State

    {

    private static State state = new Start();

    private Start()

    {

    }

    public static State Instance()

    {

    // singleton逻辑

    Console.WriteLine("Credit: 0c");

    return state;

    }

    public override void AddNickel(VendingMachine vm)

    {

    ChangeState(vm, Five.Instance());

    }

    public override void AddDime(VendingMachine vm)

    {

    ChangeState(vm, Ten.Instance());

    }

    public override void AddQuarter(VendingMachine vm)

    {

    vm.Vend();

    }

    }

    class Five : State

    {

    private static State state = new Five();

    private Five()

    {

    }

    public static State Instance()

    {

    // singleton 逻辑

    Console.WriteLine("Credit: 5c");

    return state;

    }

    public override void AddNickel(VendingMachine vm)

    {

    ChangeState(vm, Ten.Instance());

    }

    public override void AddDime(VendingMachine vm)

    {

    ChangeState(vm, Fifteen.Instance());

    }

    public override void AddQuarter(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance()); // no change returned :-)

    }

    }

    class Ten : State

    {

    private static State state = new Ten();

    private Ten()

    {

    }

    public static State Instance()

    {

    // singleton 逻辑

    Console.WriteLine("Credit: 10c");

    return state;

    }

    public override void AddNickel(VendingMachine vm)

    {

    ChangeState(vm, Fifteen.Instance());

    }

    public override void AddDime(VendingMachine vm)

    {

    ChangeState(vm, Twenty.Instance());

    }

    public override void AddQuarter(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance()); // no change returned :-)

    }

    }

    class Fifteen : State

    {

    private static State state = new Fifteen();

    private Fifteen()

    {

    }

    public static State Instance()

    {

    // singleton 逻辑

    Console.WriteLine("Credit: 15c");

    return state;

    }

    public override void AddNickel(VendingMachine vm)

    {

    ChangeState(vm, Twenty.Instance());

    }

    public override void AddDime(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance());

    }

    public override void AddQuarter(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance()); // no change returned :-)

    }

    }

    class Twenty : State

    {

    private static State state = new Twenty();

    private Twenty()

    {

    }

    public static State Instance()

    {

    // singleton 逻辑

    Console.WriteLine("Credit: 20c");

    return state;

    }

    public override void AddNickel(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance());

    }

    public override void AddDime(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance());

    }

    public override void AddQuarter(VendingMachine vm)

    {

    vm.Vend();

    ChangeState(vm, Start.Instance()); // no change returned :-)

    }

    }

    class Application

    {

    public static void Main()

    {

    int coin = 0;

    string input = null;

    VendingMachine vm = new VendingMachine();

    while (true)

    {

    Console.Write("Insert a coin (5, 10, 25): ");

    input = Console.ReadLine();

    coin = Int32.Parse(input);

    switch (coin)

    {

    case 5:

    vm.AddNickel();

    break;

    case 10:

    vm.AddDime();

    break;

    case 25:

    vm.AddQuarter();

    break;

    default:

    break;

    }

    }

    }

    }

    /*以下是某次运行时输出结果:

    The Vending Machine is now online: product costs 25c

    Credit: 0c

    Insert a coin <5, 10, 25>: 5

    Credit: 5c

    Insert a coin <5, 10, 25>: 10

    Credit: 15c

    Insert a coin <5, 10, 25>: 5

    Credit: 20c

    Insert a coin <5, 10, 25>: 5

    Dispensing product...Thank you!

    */

  • 相关阅读:
    springboot与docker
    Docker入门笔记(Centos7)
    记录VUE-CLI项目创建及初始化相关
    centos下安装mysql5.6
    GitLab权限介绍
    属性文件操作之Properties与ResourceBundle
    Shell入门基础
    JavaScript基础的记录
    Java基本排序算法
    解读闭包,这次从ECMAScript词法环境,执行上下文说起
  • 原文地址:https://www.cnblogs.com/friendwang1001/p/333437.html
Copyright © 2011-2022 走看看