设计模式学习笔记(1)

原创 2004年08月27日 12:42:00

前言
以前粗略的看过设计模式,有的看懂了,有的没看懂,有的看懂了又忘了,有的在写程序时已不知不觉在用了.
总之,现在从头学习一遍,并且开始做笔记,这样记的牢。
以后写程序也要有意识的向设计模式靠拢。
那本经典的《设计模式》准备去买一本,一共有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!

*/

[水文]出人意料的1*1卷积

0 导语 本篇主要综合和总结网络上其他的理解(个人觉得有些理解也比较牵强),由于本人没有很深的理解,所以本篇可能会出现重大理解错误,大家兼听则明。主要参考[1][2] 1*1卷积在现在的网络中大量应...
  • PeaceInMind
  • PeaceInMind
  • 2017年02月15日 18:09
  • 3429

绕过or1=1进行sql注入

突然想我们是否可以用什么方法绕过SQL注入的限制呢?到网上考察了一下,提到的方法大多都是针对AND与“’”号和“=”号过滤的突破,虽然有点进步的地方,但还是有一些关键字没有绕过,由于我不常入侵网站所以...
  • most_rabbitfishes
  • most_rabbitfishes
  • 2017年05月10日 09:04
  • 964

spring注解 @Scheduled(cron = "0 0 1 * * *")的使用来实现定时的执行任务

[java] view plain copy "font-size:14px;">初次接触定时类的小程序,还是走了很多的弯路,如今终于搞定了,总结如下:   [java] vie...
  • q1512451239
  • q1512451239
  • 2016年12月23日 15:49
  • 3434

CNN网络中的 1 x 1 卷积是什么?

http://iamaaditya.github.io/2016/03/one-by-one-convolution/ http://cs231n.github.io/convolutional-n...
  • zhangjunhit
  • zhangjunhit
  • 2017年02月15日 14:06
  • 3000

SVD奇异值分解(1)-数学基础

1. 奇异值分解(SingularValue Decomposition)是线性代数中一种重要的矩阵分解,是矩阵分析中正规矩阵酉对角化的推广。...
  • pan12jian
  • pan12jian
  • 2014年06月10日 14:33
  • 991

【转载】flex:1;详解

原文地址:https://segmentfault.com/q/1010000004080910/a-1020000004121373 仅供参考! 首先明确一点是, flex 是 flex...
  • SUNyyyB
  • SUNyyyB
  • 2017年03月28日 11:17
  • 3485

低效能的”where1=1”

网上有不少人提出过类似的问题:“看到有人写了where 1=1这样的sql,到底是什么意思?”。其实使用这种用法的开发人员一般都是在使用动态数组的sql。 让我们想象如下的场景:用户要求提供一个灵...
  • wangboxian
  • wangboxian
  • 2014年05月22日 16:53
  • 2626

Linux里的2>&1究竟是什么

我们在Linux下经常会碰到nohup command>/dev/null 2>&1 &这样形式的命令。首先我们把这条命令大概分解下首先就是一个nohup表示当前用户和系统的回话下的进城忽略响应HUP...
  • GGxiaobai
  • GGxiaobai
  • 2016年12月07日 16:11
  • 22238

java中 << 什么意思?比如1<<30

java中 飞烟步尘 | 浏览 3286 次 发布于2011-12-14 16:09 最佳答案 移位运算符就是在二进制的基础上对数字进行平移。按照...
  • evilcry2012
  • evilcry2012
  • 2017年01月06日 10:11
  • 397

[120629]初恋1/1【汉化硬盘版+高压汉化硬盘版】[带全CG存档+攻略]

游戏类型 游戏原名:初恋1/1 制作公司:tone work’s 发布日期:2012年06月29日 汉化日期:2015年12月30日 汉化小组:星冈学园文学社&脸肿汉化组 游戏类型:学园、恋爱、社团 ...
  • wangzi867258173
  • wangzi867258173
  • 2016年02月16日 19:07
  • 5990
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式学习笔记(1)
举报原因:
原因补充:

(最多只允许输入30个字)