今天很想吃麦当劳的"啃得鸡"...猛然间我对美食想入非非,越想越远...想到麦当劳、肯德基的成功之路在于规范化,流程统一,便于“复制”,使你在北京吃到的汉堡与在广州吃到的汉堡口味一样,而不像中国的小吃那样一个地方一个味道,最著名的就算“鱼香肉丝”了,如果你吃过100个地方的鱼香肉丝,那你最起码吃出来90种以上不同的口味来,悲哀...禁不住想到了一种设计模式:生成器模式。记得N久前看了“大话设计模式”中的生成器模式,今天既然有感而生,不防再把“大话设计模式”的作者的讲解与大家分享一番。
假设烤牛肉的制作包括:放盐(估计会放一点吧)、烧烤 两个步骤。如果你是顾客,你只想要烤牛肉这个产品,并且你想要5成熟的或者是7成熟的,至于怎么搞出来的你可能不关心。说了这么多跟生成器设计模式什么关系呢?仔细想一下你会发现:烤牛肉的过程是稳定的,你想要时,厨师按照流程给你建造一个就行了,如果你想将一个复杂的对象的构建与表示分离,使得同样的构建(放盐、烧烤)得到不同的表示(5成熟的牛肉、7成熟的牛肉)时,你就需要用到一种设计模式:生成器模式。
abstract class BeefBuilder
{
public abstract void 放盐();
public abstract void 烧烤();
}
5成熟BeefBuilder : BeefBuilder
{
public 5成熟BeefBuilder()
{
}
public override void 放盐()
{
放一点盐;
}
public override void 烧烤()
{
烤5成熟;
}
}
当然,7成熟的牛肉按照同样的方式去实现BeefBuilder就行了。
在客户端还要知道客户到底是想要5成熟的还是要7成熟的牛肉啊!所以还得有一个指挥类(Director),它用来控制牛肉的制作,也用它来隔离用户与制作的隔离。
class BeefDirector
{
private BeefBuilder BB;
public BeefDirector(BeefBuilder BB)//告诉指挥者(厨师)你想要几成熟的牛肉
{
this.BB=BB;
}
public void CreateBeef()//根据客户告诉你的创建烤牛肉
{
BB.放盐();
BB.烧烤();
}
}
客户端代码就很简单了:
5成熟BeefBuilder 5成熟=new 5成熟BeefBuilder();
BeefDirector BD=new BeefDirector(5成熟);
BD.CreateBeef();
总结:BeefBuilder是指创建对象的各个部件指定的抽象接口,5成熟BeefBuilder是具体的创建者。BeefDirector是指挥者,即是构建一个使用BeefBuilder的接口的对象。
万变不离其宗:掌握最根本的才是掌握最精髓的。
c#的字段就是指私有域(变量)
class A
{
int i;
public int I
{
get{....}
set{....}
}
}
其中,i是字段,I是属性,
字段是属于一个类的,在类中定义(注意:是类中,而不是类中的某个方法或属性中)
在本类中可以用this.字段名访问,且本类中的所有属性、方法等都可以访问,也就是说它的作用域是整个类。
而局部变量是属于一个函数或语句块的,它的作用域是从定义开始,到离开语句块。
一、域:表示与对象或类相关联的变量
在下面的代码中,类A包含了三个域:公有的X和Y,以及私有的z。
class A
{
public int x;
public string y;
private float z;
}
二、字段:是与对象或类相关联的变量(私有变量)。
当一个字段声明中含有static修饰符时,由该声明引入的字段为静态字段(static field)。它只标识了一个存储位置。不管创建了多少个类实例,静态字段都只会有一个副本。
当一个字段声明中不含有static修饰符时,由该声明引入的字段为实例字段(instance field)。类的每个实例都包含了该类的所有实例字段的一个单独副本。
三、属性:
为了类的封装性,一般是把字段设为Private, 把属性设为公有来操作字段。
属性(property)是字段的自然扩展,两者都是具有关联类型的命名成员,而且访问字段和属性的语法是相同的。然而,属性与字段不同,不表示存储位置。相反,属性有访问器(accessor),这些访问器指定在它们的值被读取或写入时需执行的语句。
属性的声明类似于字段,不同之处在于属性的声明以定界符{}之间的get访问器和/或set访问器结束,而不是分号。同时包含get访问器和set访问器的属性称为读写属性(read-write property)。只具有get访问器的属性称为只读属性(read-only property)。只具有set访问器的属性称为只写属性(write-only property)。
get访问器相当于一个具有属性类型返回值的无参数方法。除了作为赋值的目标外,当在表达式中引用属性时,会调用该属性的get访问器以计算该属性的值。
set访问器相当于一个具有单个名为value的参数和无返回类型的方法。当一个属性作为赋值的目标,或者作为++或--运算符的操作数被引用时,就会调用set访问器,所传递的自变量将提供新值。首先抛砖引玉,谈一下本人对委托和事件的理解,然后再引用jimmy.zhang所讲的委托和事件的例子,希望能对还不是很清楚委托和事件的朋友有所帮助。
本人的理解:
委托:
1、 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性.
2、 委托只是定义了一个方法的原型.它的实现包含:
- 声明委托类型
- 定义与委托类型符合的方法
- 声明委托变量
- 初始化委托实例
- 调用委托
3、 注意: 定义一个委托是指定义一个新类,委托实现为派生于基类System.MulticastDelegate的类, System.MulticastDelegate又派生于基类System.Delegate.C#编译器知道这个类,会使用其委托语法,因此我们不需要详细了解此类内部实现,这是C#与基类共同合作,使编程更易完成.
4、 注意: 在术语方面有个问题,类有两个不同的术语中:‘类’表示广泛的定义,‘对象’表示类的实例,但委托只有一个术语,在创建委托实例时,所创建的委托实例仍称为委托.
5、 给定委托的实例可以表示任何类型的任何对象上的实例方法或静态方法---只要方法的签名与委托符合.
事件:
1、 事件处理程序不能有返回值.
2、 事件注册方法类似于多播委托,可多播委托是根据注册方法时顺序执行,而事件却没有,方法执行顺序不可预估.
3、 .NET建议标准声明事件的委托必须无返回值,则有object, EventArgs 两参数.第一个参数是表示引发事件的对象,第二个参数是包含有关事件的其他有用信息的对象,可记录发生事件现场.可直接使用系统提供的 EventHandler.
4、 虽然声明事件时使用public修饰符,但编译成IL时仍转换成private.
5、 事件是委托的进一步封装.
他人的精华:
想必大家都知道网上一些讲委托和事件的例子,本人认为jimmy.zhang的这篇写的最好,最容易让还不是很清楚委托与事件的朋友豁然开朗。原文地址:http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html
ref与out都是C#的关键字,所实现的功能也基本相同,都是指定一个参数按照引用传递,但是它们在使用时还是有一定的区别:
1.使用out关键字时,必须在离开函数体前给其赋值,而Ref传进去的参数可以不被修改。
2.out关键字传进去的参数调用前可以不用初始化,但是Ref穿进去的参数调用前必须初始化。
如:int i
MyMethod(ref i)//语法错误
MyMethod(out i)//正确
3.out关键字穿进去的参数不能直接被使用,而Ref则可以
如:MyMethod(ref int i)
{
int j=i;//正确
}
MyMethod(out int i){
int j=i;//语法错误
}
使用时各有优缺点,系统对ref的限制要少一点,out关键字传递参数对于函数体内部是不可见的,也就是说out关键字传进来的参数不可使用,并且在离开函数体前也一定要给out传进来的参数赋一个值。
若方法中一个带out/ref关键字,一个不带,则可以完成方法的重载,如下:
class RefOutOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(out int i) { }
}

