设计模式学习总结

抽象工厂者模式

类图结构

优点:

1、 封装性,每个产品的实现类不是高层模块关心的,它只关心接口、抽象表示,它不关心对象是如何被创建出来的,对象的创建是由工厂类负责的,因此只要知道该产品的工厂类是谁,就能够创建出一个需要的对象,省时省力;

2、 产品族内的约束为非公开状态。产品族内的约束条件对调用工厂类的高层模块来说是透明的,它不需要知道其中的约束,它只关心具体的产品就可以,产品族内的约束实在工厂内实现的。

缺点:

   抽象工厂最大的缺点就是产品族扩展非常困难。以上述类图为例,如果要增加一个产品C,即产品族由原来的2个增加到3个,这时我们就要将抽象类AbstractCreator增加一个方法createProductC(),然后两个实现类都要修改,这就违反了开闭原则,而且抽象类和接口是一个契约,改变契约,所有与契约相关的代码都要修改,那么这段代码就成了有毒代码,会对整个程序带来危害。

实现要点

在抽象工厂模式中,选用哪种产品族的问题,需要采用工厂方法或简单工厂模式来配合解决。

抽象工厂模式和工厂方法模式一样,都把对象的创建延迟到了他的子类中。

具体的工厂类可以设计成单例类,他只向外界提供自己唯一的实例。

与其他工厂模式的联系和异同:

抽象工厂模式中的具体工厂负责生产一个产品族的产品。而产品族的增加只需要增加与其对应的具体工厂。

3种工厂模式都是创建型模式,都是创建对象的,但都把产品具体创建的过程给隐藏了。

工厂方法模式是针对一种产品结构,而抽象工厂模式是针对多种产品结构。

适用性:

在以下情况下应当考虑使用抽象工厂模式:

一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

这个系统有多于一个的产品族,而系统只消费其中某一产品族。

同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

注意事项:

   抽象工厂模式对产品族扩展比较困难,但是对产品等级的扩展时很容易的,即横向扩展容易,纵向扩展困难。

最佳实践:

   抽象工厂模式是一个简单的模式,使用场景非常多,在软件开发过程中,涉及不同操作系统的时候,都可以考虑抽象工厂模式。例如一个应用需要在三个不同平台(windows、linux、android)上运行,不需要涉及三套不同的应用,通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都是非常类似的,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。

建造者模式

类图结构:

1.建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。模式中直接创建产品对象的是具体建造者(Concrete Builder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

2.具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程。在建造过程完成后,提供产品的实例。

3.导演(Director):担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

4.产品(Product)角色:产品便是建造中的复杂对象。指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

优点:

1、 封装性。使用建造者模式可以使客户端不必知道产品内部组成的细节;

2、 建造者独立,容易扩展

3、 便于控制细节风险。由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

实现要点:

1.建造者模式主要用于“分步骤构建一个复杂的对象”,在这其中“每个步骤”是一个稳定的算法,而复杂对象的各个步骤之间则经常变化。

2.上一篇所说的抽象工厂模式解决“系列对象”的需求变化,而建造者模式解决单个对象里“对象部分”的需求变化。

产品不需要抽象类,特别是由于创建对象的算法复杂而导致使用此模式的情况下或者此模式应用于产品的生成过程,其最终结果可能差异很大,不大可能提炼出一个抽象产品类。

3.创建者中的创建子部件的接口方法不是抽象方法而是空方法,不进行任何操作,具体的创建者只需要覆盖需要的方法就可以,但是这也不是绝对的,特别是类似文本转换这种情况下,缺省的方法将输入原封不动的输出是合理的缺省操作。

适用性:

以下情况应当使用建造者模式:

1、相同的方法,不同的执行顺序,产生不同的事件结果时。

2、多个部件或者零件,都可以装配到一个对象当中,但是产生的运行结果又不相同,可以使用该模式。
3、产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常适合。
4、 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到,也可以采用建造者模式封装该对象的创建过程。这种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段没有发觉,而要通创建者柔滑创建过程,本身已经违反设计的最初目标。

效果

1、建造者模式的使用使得产品的内部表象可以独立的变化。使用建造者模式可以使客户端不必知道产品内部组成的细节。
2、每一个Builder都相对独立,而与其它的Builder无关。
3、可使对构造过程更加精细控制。

4、将构建代码和实现代码分开。

5、建造者模式的缺点在于难于应付“分步骤构建算法”的需求变动。

两种设计模式的对比

两种设计模式非常的相似,但是创建者模式最主要的功能室基本方法的调用顺序的安排,也就是这些基本方法都已经实现,通俗的说就是零件的装配,顺序不同产生的结果也不;而工厂方法则重点是创建,创建零件是他的主要职责,组装顺序则不是他关心的。两种设计模式的侧重点是不相同的。

 

第二篇:大话设计模式学习总结

C#大话设计模式学习总结

一、工厂模式

面向对象的三个特性:封装,继承和多态

1.封装

Class Operate

{

   private double _numberA;

   private double _numberB;

  

   public double NumberA

   {

      get{return _numberA;}

      set{_numberA = value;}

   }

   public double _numberB

   {

      get{return _numberB;}

      set{_numberB = value;}

   }

}

2.继承

//父类

Class Operation

{

   private double _numberA;

   private double _numberB;

  

   public double NumberA

   {

      get{return _numberA;}

      set{_numberA = value;}

   }

   public double _numberB

   {

      get{return _numberB;}

      set{_numberB = value;}

   }

   //父类的虚方法

   public virtual double GetResult()

   {

      double result = 0;

      return result;

   }

}

//加法运算子类

Class OperationAdd:Operation

{

   public override double GetResult()

   {

      double result = 0;

      result = NumberA + NumberB;

      return result;

   }

}

//减法运算子类

Class OperationSub:Operation

{

   public override double GetResult()

   {

      double result = 0;

      result = NumberA - NumberB;

      return result;

   }

}

//乘法运算子类

Class OperationMul:Operation

{

   public override double GetResult()

   {

      double result = 0;

      result = NumberA * NumberB;

      return result;

   }

}

//除法运算子类

Class OperationDiv:Operation

{

   public override double GetResult()

   {

      double result = 0;

      result = NumberA / NumberB;

      return result;

   }

}

3.多态

一句话:允许将子类类型的指针赋值给父类类型的指针。

接口

1、C#接口的作用 :  

C# 接口是一个让很多初学C#者容易迷糊的东西,用起来好像很简单,定义接口,里面包含方法,但没有方法具体实现的代码,然后在继承该接口的类里面要实现接口 的所有方法的代码,但没有真正认识到接口的作用的时候就觉得用接口是多此一举,当然你这样想那是绝对绝对错误的,比尔盖茨的微软请的员工都是比盖茨还聪明 的人,他们的C#能添这样的多足吗?!关于接口的作用,网上有一位就真的深入浅出给我们做了很好理解的分析。  

我们定义一个接口 

public interface IBark 

{

    void Bark(); 

再定义一个类,继承于IBark,并且必需实现其中的Bark()方法 

public class Dog:IBark 

    public Dog(){}

    public void Bark()

   { 

       Consol.write("汪汪");      

   }

然后,声明Dog的一个实例,并调用Bark()方法       

Dog 旺财=new Dog();       

旺财.Bark(); 

试想一样,若是想调用Bark()方法,只需要在Dog()中声明这样的一个方法不就行了吗,干什么还要用接口呢.因为接口中并没有Bark()具体实现.真的实现还是要在Dog()中.那么使用接口不是多此一举吗? 

还 有人是这样说的:从接口的定义方面来说,接口其实就是类和类之间的一种协定,一种约束.还拿上面的例子来说.所有继承了IBark接口的类中必需实现 Bark()方法.那么从用户

(使用类的用户)的角度来说,如果他知道了某个类是继承于IBark接口,那么他就可以放心大胆的调用Bark()方法,而 不用管Bark()方法具体是如何实现的.比如,我们另外写了一个类. 

public class Cat:IBark

   public Cat(){}

   public void Bark()

   {

             Consol.write("喵喵");

   }

}

当用户用到Cat类或是Dog类的时候,知道他们继承于IBark,那么不用管类里的具体实现,而就可以直接调用Bark()方法,因为这两个类中肯定有关于Bark()方法的具体实现.  

如 果我们从设计的角度来看.一个项目中用若干个类需要去编写,由于这些类比较复杂,工作量比较大,这样每个类就需要占用一个工作人员进行编写.比如A程序员 去定Dog类,B程序员去写Cat类.这两个类本来没什么联系的,可是由于用户需要他们都实现一个关于"叫"的方法.这就要对他们进行一种约束.让他们都 继承于IBark接口,目的是方便统一管理.另一个是方便调用.当然了,不使用接口一样可以达到目的.只不过这样的话,这种约束就不那么明显,如果这样类 还有Duck类等等,比较多的时候难免有人会漏掉这样方法.所以说还是通过接口更可靠一些,约束力更强一些.

2、C#中接口的深入浅出:  

通过学习对C#中接口的作用有了更进一步的理解,拿出来跟大家分享一下,有说的不对的地方请大家指教。 

    假设我们公司有两种程序员:VB程序员,指的是用VB写程序的程序员,用clsVBProgramer这个类表示;Delphi程序员指的是用 Delphi写程序的程序员,用clsDelphiProgramer这个类来表示。每个类都有一个WriteCode()方法。定义如下:

class clsVBProgramer()

 { 

   ....

    WriteCode()

   { 

      //用VB语言写代码;

   } 

   .... 

}

class clsDelphiProgramer() 

   .... 

   WriteCode() 

   { 

      //用Delphi语言写代码;

   }

   .... 

现在公司来了一个项目,要求派某个程序员写一个程序。 

class clsProject() 

   .... 

   WritePrograme(clsVBProgramer programer)

   //用VB写代码 

   {

      programer.WriteCode(); 

   } 

   WritePrograme(clsDelphiProgramer programer)

   //重载方法,用Delphi写代码 

   {

      programer.WriteCode(); 

   }

   ...... 

在主程序中我们可以这样写: 

main() 

   clsProject proj=new clsProject;    //如果需要用VB写代码 

   clsVBProgramer programer1=new clsVBProgramer;    

   proj.WritePrograme(programer1);    //如果需要用Delphi写代码 

   clsDelphiProgramer programer2=new clsDelphiProgramer;    

   proj.WritePrograme(programer2); 

但是如果这时公司又来了一个C#程序员,我们怎么改这段程序,使它能够实现用 C#写程序的功能呢?我们需要增加一个新类clsCSharpProgramer,同时在此clsProject这个类中要再次重载 

WritePrograme(clsCSharpProgramer programer)方法。这下麻烦多了。如果还有C程序员,C++程序员,JAVA程序员呢。麻烦大了! 

但是如果改用接口,就完全不一样了: 首先声明一个程序员接口: 

interface IProgramer()

   WriteCode(); 

然后声明两个类,并实现IProgramer接口: 

class clsVBProgramer():IProgramer 

   ....

    WriteCode() 

   { 

      //用VB语言写代码;

   } 

   .... 

}

class clsDelphiProgramer():IProgramer

   .... 

   WriteCode()

   {

      //用Delphi语言写代码;

   }

   .... 

对clsProject这个类进行一下修改: 

class clsProject() 

   .... 

   WritePrograme(IProgramer programer) 

   { 

      programer.WriteCode();

      //写代码 

   } 

   ...... 

main() 

   clsProject proj=new clsProject;    

   IProgramer programer;    //如果需要用VB写代码    

   programer=new clsVBProgramer;    

   proj.WritePrograme(programer);    //如果需要用Delphi写代码 

   programer=new clsDelphiProgramer;    

   proj.WritePrograme(programer);    

如果再有C#,C,C++,JAVA这样的程序员添加进来的话,我们只需把它们相关的类加进来,然后在main()中稍做修改就OK了。扩充性特别好! 

另外我们如果把clsProject这个类封成一个组件,那么当我们的用户需要要扩充功能的时候,我们只需要在外部做很小的修改就能实现,可以说根本就用不着改动我们已经封好组件!是不是很方便,很强大!

二、策略模式

策略模式涉及三个角色

1.环境(Context)角色持有一个Strategy类的引用。

2.抽象策略(Strategy)角色这是一个抽象角色,通常有一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口。

3.具体策略(Concrete Strategy)角色包装了相关的算法和行为。

依赖注入(dependency injection)是需要IoC容器提供的,比如spring.net.

声明一个动物对象,名称animal,然后将animal实例化成猫类的对象

方法一:实例化一个类Animal animal = new Cat();

方法二:using System.Reflection;

假设当前程序集是AnimalSystem,名称空间也是AnimalSystem

那么使用反射技术实例化一个类就是Animal animal = (Animal)Assembly.Load("AnimalSystem").CreateInstance("AnimalSystem.Cat");

关键是:Assembly.Load("程序集名称").CreateInstance("名称空间.类名称")

设计模式的几大设计原则:

1.单一职责原则是指对于一个类而言,应该仅有一个因其他变化的原因。

2.开放-封闭原则是说对扩展开发,对修改关闭,具体说就是我们设计一个模块时,使该模块可以不再被修改的前提下被扩展。

3.依赖到转原则是抽象不应该依赖细节,细节应该依赖于抽象。说白了就是要针对接口编程,不针对实现编程

4.迪米特法则LoD,也叫最少知识原则,简单的说,就是如果两个类不必彼此直接通信,那么这两个类就不应该发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

5.门面模式或外观模式要求一个子系统的外部和其内部的通信必须通过一个统一的门面Facade对象进行。门面模式提供一个高层次的接口,使得子系统更容易使用。

门面模式图解

Facade门面角色:客户端可以调用这个角色的方法。此角色知晓相关的(一个或多个)子系统的功能和责任,在正常情况下,本角色会将所有从客户端发来的请求委派到相应的子系统中去。

subsystem子系统角色:可以同时有一个或多个子系统,每一个子系统都不是一个单独的类,而是一个类的集合,每一个子系统都可以直接被客户端调用,或者被门面角色调用,子系统并不知道门面的存在,对于子系统而言,门面仅仅是一个客户端而已。

三层架构 

1.UI层(表示层,界面层,表现层)  UI

2.业务逻辑层(Business Logic Layer)BLL

3.数据访问层(Data Access Layer)DAL

C#设计模式

创建型模式:1.简单工厂模式,2.工厂方法模式,3.抽象工厂模式,4.单件模式,5.生成器模式,6.原型模式

创建型模式是创建对象而不是直接实例化对象,这会使程序在判断给定情况下创建哪一个对象时更为灵活。

结构型模式:7.适配器模式,8.桥接模式,9.组合模式,10.装饰模式,11.外观模式,12.享元模式,13.代理模式

结构型模式可以将一组对象组合成更大的结构,例如复杂的用户界面和报表数据。

行为型模式:14.职责链,15.命令模式,16.解释器模式,17.迭代器模式,18.中介者模式,19.备忘录模式,20.观察者模式,21.状态模式,22.策略模式,23. 模板方法模式,24.访问者模式

行为型模式定义系统内对对象间的通信,以及复杂程序中的流程控制。

一个常被引用的模式是Smalltalk(Krasmer and Pope 1988)的模型-视图-控制器(Model-View-Controller)框架

数据模型:包括程序的计算部分

视图:表示用户界面

控制器:定义用户和视图的交互方式

对象组合:

C#中的字符是16位的宽度,可以表示非拉丁语言中的所有字符,它是使用一种双字节吗的字符编码系统

C#和java的区别:

1.许多系统对象都有相同的方法名,只是在大小写形式上有区别。

2.C#不提供throws关键字,该关键字使编译器你是否捕获了一个方法抛出的异常。

3.C#对布局管理器有更多的限制,因为他是以Windows系统为中心的,大多数时候采取的是图形元素的绝对位置。

4.C#允许运算符重载。

5.C#引进了代理和索引器的思想。

6.C#有枚举类型。

7.C#有不安全模式,在这种模式下可以使用指针。

8.必须专门声明一个方法能被覆盖及一个方法能覆盖另一个方法。

9.不能通过声明来区别继承和接口实现,它们的声明方式是一样的。

10.switch语句允许使用字符串变量,如果变量没有被匹配,必须有一个默认情况,否则会出现错误,break语句是必需的。

11.布尔类型在C#中为bool,在java中为boolean。

C#代理:

是一个类方法的原型,既可以是静态也可以是来自某个类实例,可以将代理声明为一种类型声明

private delegate string fTxDelegate(string s);

fTxDelegate ftx;  //代理变量

public class capital

{

   public string fixText(string s)

   {

      return s.ToUpper();

   }

}

public class Lower

{

   public static string fixText(string s)

   {

      return s.ToLower();

   }

}

把fixText方法赋给一个代理变量

...

ftx = new fTxDelegate(new capital().fixText);

...

ftx = new fTxDelegate(Lower.fixText);

C#索引器:

public class BitList

{

   private int number;

   public BitList(string $num)

   {

      number = Convert.ToInt32($num);

   }

   public int this[int index]

   {

      get

      {

         int val = number>>index;

         return val & 1;

      }

   }

}

C#重载运算符:

public static Complex operator +(Complex c1,Complex c2)

{

   return new Complex(c1.real + c2.real,c1.imaginary + c2.imaginary);

}

namespace CSharpPats

{

   public class Rectangle

   {

      private int x,y,w,h;

      protected Pen rpen;

      public Rectangle(int x_,int y_,int w_,int h_)

      {

         x = x_

         y = y_;

         w = w_;

         h = h_;

         rpen = new Pen(Color.Black);

      }

      public void Draw(Graphics g)

      {

         g.DrawRectangle(rpen,x,y,w,h);

      }

   }

}

CSharpPats.Rectangle rect;

private void Init()

{

   rect = new CSharpPats.Rectangle(10,20,70,100);

}

public Form1()

{

   InitializeComponent();

   Init();

}

pic框画图事件

private void pic_Paint(object sender,PaintEventArgs e)

{

   Graphics g = e.Graphics;

   rect.Draw(g);

}

下面需要创建一个square类

namespace CSharpPats

{

   public class Square:Rectangle

   {

      public Square(int x,int y,int w):base(x,y,w,w)

      {

         ...

      }

   }

}

public 公共的,都能访问

private 只能在该类内部访问

protected 只能在该类及派生类里访问

如果基类中有一个方法,而想在派生类中覆盖它,应该把基类中的方法声明为virtual,它的意义是让派生类中具有同样名字和参数标识的方法被调用,而不是调用基类中的方法。然后再派生类中必须用override关键字声明该方法。

如果基类中方法没有声明为virtu时,可以使用另一种期待基类中方法的方式,就是在派生类中声明方法时使用new关键字,这样做能有效地隐藏基类中同一名字(与参数无关)的方法,这种情况下,不能在派生类中调用基类中的方法,而且必须把所有的代码都放在替换方法中。

eg:public new void Draw(Graphics g)

{

   g.DrawRectangle(rpen,x,y,w,h);

   g.DrawRectangle(rpen,x + 5,y + 5,w,h);

}

C#接口:

本质上是一个规约,即一个类包含接口所描述的所有方法,接口声明方法的签名,不包含方法主体。

如果一个类实现了一个接口,就要提供接口中每一个方法的实现过程

C#抽象类:

声明一个或多个没有实现的方法,如果把一个方法声明为抽象方法,那么也需要把类声明为抽象的。

不能创建抽象类的实例,只能创建实现了抽象方法的派生类的实例

public abstract class Shape

{

   ...

   public Shape(int x,int y,int w,int h)

   {

      ...

   }

  

   public abstract void Draw(Graphlics g)

   {

      ...

   }

}

public class Rectangle:Shape

{

   public Retangle(int x,int y,int w,int h):base(x,y,w,h)

   {

   }

  

   public override void Draw(Graphics g)

   {

      ...

   }

}

接口和抽象类的比较:

1.创建一个接口就是创建了一个或多个方法的定义。

2.每个实现该接口的类中必须实现这些方法。

3.系统不会生成任何默认的方法代码,必须自己写代码实现。

4.提供了一种让一个类成为两个类的子类的方式:一个是继承,一个是来自子接口。

5.创建一个抽象类就是创建了这样一个基类,它可能有一个或多个完整的、可以工作的方法,但至少有一个方法未实现并声明为抽象的。

6.不能实例化一个抽象类,必须从它派生出类,这些类包含了抽象方法的实现过程。

7.如果一个抽象类的所有方法在基类中都未实现,它本质上就等同于一个接口。但限制条件是:一个类不能从它继承,也不能继承其他类层次结构,而是用接口可以这样做。

8.抽象类的作用是对派生类如何工作提供了一个基类定义、允许程序员在不同的派生类中填充这些实现过程。

9.创建一种带空方法的基类,这些空方法可以保证所有的派生类都能够编译,但是每个事件的默认操作是根本什么都不做。

C#数组、文件和异常

数组:

int[] x = new int[10];

float[] xy = new float[10];

集合对象:

ArrayList arrList = new ArrayList();

HashTable

HashTable hash = new HashTable();

hash.Add("fred","freddy");

SortedList

SortedList sortedList = new SortedList();

sortedList.Add("sam","sammy");

Stack(堆栈)

Queue(队列)

C#文件

File对象都是静态的,不能用new实例化,而是直接使用

File.Exists("文件名");

File.Delete("文件名");

StreamReader ts = File.OpenText("文件名");

FileStream fs = File.OpenRead("foo2.any");

File.FileExists(filename) 若文件存在,则为true

File.Delete(filename) 删除文件

File.AppendText(string) 追加文本

File.Copy(fromFile,toFile) 拷贝一个文件

File.Move(fromFile,toFile) 移动文件,删除旧的文件

File.GetExtension(filename) 返回文件的扩展名

File.HasExtension(filename) 若文件有扩展名,则为true

读文本文件

StreamReader sr = File.OpenText("foo1.txt");

string s = sr.ReadLine();

写文本文件

StreamWriter sw = File.CreateText("foo3.txt");

sw.WriteLine("Hello file");

StreamWriter sw = new StreamWriter("foo3.txt",true);

检测文件末尾

1.查找空null异常

2.查找数据流的末尾

eg:

private StreamReader sr;

private bool eof;

public String ReadNextLine()

{

   string s = sr.ReadLine();

   if(s == null)

   {

      eof = true;

   }

   return s;

}

public bool fEof()

{

   return eof;

}

另一种保证读数据不会超过文件末尾的方法是:使用Stream的Peek方法在都数据前先查看一下,Peek方法返回文件中下一个字符的ASCII码,如果没有字符则返回-1

eg:

private StreamReader sr;

private bool eof;

public String ReadNextLine()

{

   string s = "";

   if(sr.Peek() > 0)

   {

      s = sr.ReadLine();

   }

   else

   {

      eof = true;

   }

   return s;

}

csFile

public class csFile

{

   private string fileName;

   StreamReader sr;

   StreamWriter sw;

   private bool opened,writeOpened;

   public csFile()

   {

      Init();

   }

   private void Init()

   {

      opened = false;

      writeOpened = false;

   }

  

   public csFile(string file_name)

   {

      fileName = file_name;

      Init();

   }

}

打开读数据的文件的方法:1.一个方法包含了文件的名字,2.将文件名做为参数。

public bool OpenForRead(string file_name)

{

   fileName = file_name;

   try

   {

      sr = new StreamReader(fileName);

      opened = true;

   }

   catch(FileNotFoundException e)

   {

      return false;

   }

   return true;

}

public string ReadNextLine()

{

   return sr.ReadLine();

}

打开写数据的文件的方法,并向其中写入若干行文本。

public void WriteNextLine(strin s)

{

   sw.WriteLine(s);

}

public bool OpenForWrite()

{

   return OpenForWrite(fileName);

}

public bool OpenForWrite(string file_name)

{

   try

   {

      sw = new StreamWriter(file_name);

      fileName = file_name;

      writeOpened = true;

      return true;

   }

   catch(FileNotFoundException e)

   {

      return false;

   }

}

这里才正式进入设计模式课程

首先是创建型模式Creational Pattern

创建型模式都涉及到创建对象实例的方式,因为程序不应该依赖对象如何创建和如何安排。

那么我们将创建过程抽象成一个专门的"创建器"类

工厂方法模式Factory Method Pattern

抽象工厂模式Abstract Factory Pattern

单件模式Singleton Pattern

生成器模式Builder Pattern

原型模式Prototype Pattern

简单工厂模式Simple Factory Pattern

(firstname lastname或者lastname,firstname)

public class Namer

{

   protected string fName,lName;

   public string GetFname()

   {

      return fName;

   }

   public string GetLname()

   {

      return lName;

   }

}

派生类

public class FirstName:Namer

{

   public FirstName(string name)

   {

      int i = name.Trim().IndexOf(" ");

      if(i > 0)

      {

         fName = name.Substring(0,i).Trim();

         lName = name.Substring(i+1).Trim();

      }

      else

      {

         lName = name;

         fName = "";

      }

   }

}

public class LastName:Namer

{

   public LastName(string name)

   {

      int i = name.IndexOf(",");

      if(i > 0)

      {

         lName = name.Substring(0,i).Trim();

         fName = name.Substring(i+1).Trim();

      }

      else

      {

         lName = name;

         fName = "";

      }

   }

}

构造简单工厂

public class NameFactory

{

   public NameFactory(){}

   public Namer GetName(string name)

   {

      int i = name.IndexOf(",");

      if(i > 0)

      {

         return new LastName(name);

      }

      else

      {

         return new FirstName(name);

      }

   }

}

使用工厂(按钮点击事件还是别的都可)

//NameFactory  nameFact = new NameFactory();

Namer nm = nameFact.GetName(txtName.text);

txtFirst.Text = nm.GetFname();

txtLast.Text = nm.GetLname();

相关推荐