摘要: 来自:http://www.cnblogs.com/yyw84/archive/2006/12/27/604544.html一、什么是委托 下面引用自 MSDN委托类型声明的格式如下:publicdelegatevoidTestDelegate(stringmessage);delegate 关键字用于声明一个引用类型,该引用类型可用于封装命名方法或匿名方法。委托类似于 C++ 中的函数指针;但是... 阅读全文
posted @ 2008-08-05 14:56 破孩 阅读(54) | 评论 (0)编辑
     摘要: 引自:http://blog.csdn.net/lynnlin1122/archive/2008/06/21/2573498.aspx委托、事件与Observer设计模式 范例说明  上面的例子已不足以再进行下面的讲解了,我们来看一个新的范例,因为之前已经介绍了很多的内容,所以本节的进度会稍微快一些:  假设我们有个高档的热水器,我们给它通上电,当水温超过95度的时候:1、扬声器会开始发出语音,告... 阅读全文
posted @ 2008-08-01 15:55 破孩 阅读(45) | 评论 (0)编辑

来自:http://www.itisedu.com/phrase/200603061631585.html

设计模式

因业务需要,“中科永联”正式更名为“中程在线”,欢迎大家浏览新网站“中程在线信息产业培训网

中科永联高级技术培训中心(www.itisedu.com

      设计模式Design pattern)是一套被反复使用、多数人知晓的、经过分编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

      毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。

      GoF的“设计模式”是第一次将设计模式提升到理论高度,并将之规范化,本书提出了23种基本设计模式,自此,在可复用面向对象软件的发展过程中,新的大量的设计模式不断出现。

一、设计模式和框架

      现在,可复用面向对象软件系统现在一般划分为三大类:应用程序工具箱和框架(Framework),我们平时开发的具体软件都是应用程序;Java的API属于工具箱;而框架是构成一类特定软件可复用设计的一组相互协作的类。EJB(EnterpriseJavaBeans)是Java应用于企业计算的框架.

      框架通常定义了应用体系的整体结构类和对象的关系等等设计参数,以便于具体应用实现者能集中精力于应用本身的特定细节。框架主要记录软件应用中共同的设计决策,框架强调设计复用,因此框架设计中必然要使用设计模式.

      另外,设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发者如果突然接触EJBJ2EE等框架,会觉得特别难学,难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器。

二、设计模式的原则

   近年来,大家都开始注意设计模式。那么,到底我们为什么要用设计模式呢?这么多设计模式为什么要这么设计呢?说实话,以前我还真没搞清楚。就是看大家一口一个"Design pattern",心就有点发虚。于是就买了本"四人帮"的设计模式,结果看得似懂非懂:看得时候好像是懂了,过一会就忘了。可能是本人比较"愚钝"吧:))最近,有了点感悟。"独乐不如众乐",与大家分享一下,还望指教!
    为什么要提倡"Design Pattern"呢?根本原因是为了代码复用,增加可维护性。那么怎么才能实现代码复用呢?OO界有前辈的几个原则:"开-闭"原则(Open Closed Principal)、里氏代换原则、合成复用原则。设计模式就是实现了这些原则,从而达到了代码复用、增加可维护性的目的。

    1、"开-闭"原则

    此原则是由"Bertrand Meyer"提出的。原文是:"Software entities should be open for extension,but closed for modification"。就是说模块应对扩展开放,而对修改关闭。模块应尽量在不修改原(是"原",指原来的代码)代码的情况下进行扩展。那么怎么扩展呢?我们看工厂模式"factory pattern":假设中关村有一个卖盗版盘和毛片的小子,我们给他设计一"光盘销售管理软件"。我们应该先设计一"光盘"接口。如图:
[pre]______________
|<>|
| 光盘        |
|_____________|
|+卖()        |
|             |
|_____________|[/pre]
而盗版盘和毛片是其子类。小子通过"DiscFactory"来管理这些光盘。代码为:

public class DiscFactory{
    public static 光盘 getDisc(java/lang/String.java.html" target="_blank">String name){
       return (光盘)java/lang/Class.java.html" target="_blank">Class.forName(name).getInstance();
    }
}
有人要买盗版盘,怎么实现呢?

public class 小子{
    public static void main(java/lang/String.java.html" target="_blank">String[] args){
        光盘 d=DiscFactory.getDisc("盗版盘");
        光盘.卖();
    }
}

    如果有一天,这小子良心发现了,开始卖正版软件。没关系,我们只要再创建一个"光盘"的子类"正版软件"就可以了。不需要修改原结构和代码。怎么样?对扩展开发,对修改关闭。"开-闭原则"
    工厂模式是对具体产品进行扩展,有的项目可能需要更多的扩展性,要对这个"工厂"也进行扩展,那就成了"抽象工厂模式"。

    2、里氏代换原则

里氏代换原则是由"Barbara Liskov"提出的。如果调用的是父类的话,那么换成子类也完全可以运行。比如:
       光盘 d=new 盗版盘();
       d.卖();
    现在要将"盗版盘"类改为"毛片"类,没问题,完全可以运行。Java编译程序会检查程序是否符合里氏代换原则。还记得java继承的一个原则吗?子类overload方法的访问权限不能小于父类对应方法的访问权限。比如"光盘"中的方法"卖"访问权限是"public",那么"盗版盘"和"毛片"中的"卖"方法就不能是package或private,编译不能通过。为什么要这样呢?你想啊:如果"盗版盘"的"卖"方法是private。那么下面这段代码就不能执行了:
            光盘 d=new 盗版盘();
            d.卖();
可以说:里氏代换原则是继承复用的一个基础。

    3、合成复用原则

    就是说要少用继承,多用合成关系来实现。我曾经这样写过程序:有几个类要与数据库打交道,就写了一个数据库操作的类,然后别的跟数据库打交道的类都继承这个。结果后来,我修改了数据库操作类的一个方法,各个类都需要改动。"牵一发而动全身"!面向对象是要把波动限制在尽量小的范围。


    在Java中,应尽量针对Interface编程,而非实现类。这样,更换子类不会影响调用它方法的代码。要让各个类尽可能少的跟别人联系,"不要与陌生人说话"。这样,城门失火,才不至于殃及池鱼。扩展性和维护性才能提高

    理解了这些原则,再看设计模式,只是在具体问题上怎么实现这些原则而已。张无忌学太极拳,忘记了所有招式,打倒了"玄幂二老",所谓"心中无招"。设计模式可谓招数,如果先学通了各种模式,又忘掉了所有模式而随心所欲,可谓OO之最高境界。呵呵,搞笑,搞笑!(JR)

      4 依赖倒转原则

抽象不应该依赖与细节,细节应当依赖与抽象。

要针对接口编程,而不是针对实现编程。

传递参数,或者在组合聚合关系中,尽量引用层次高的类。

主要是在构造对象时可以动态的创建各种具体对象,当然如果一些具体类比较稳定,就不必在弄一个抽象类做它的父类,这样有画舌添足的感觉

      5 接口隔离原则

定制服务的例子,每一个接口应该是一种角色,不多不少,不干不该干的事,该干的事都要干

      6 抽象类

抽象类不会有实例,一般作为父类为子类继承,一般包含这个系的共同属性和方法。

注意:好的继承关系中,只有叶节点是具体类,其他节点应该都是抽象类,也就是说具体类

是不被继承的。将尽可能多的共同代码放到抽象类中。

      7 迪米特法则

最少知识原则。不要和陌生人说话。

三、一个模式的四个基本要素

      设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。


1. 模式名称(pattern name)

      一个助记名,它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我们的设计词汇。设计模式允许我们在较高的抽象层次上进行设计。基于一个模式词汇表,我们自己以及同事之间就可以讨论模式并在编写文档时使用它们。模式名可以帮助我们思考,便于我们与其他人交流设计思想及设计结果。找到恰当的模式名也是我们设计模式编目工作的难点之一。

2. 问题(problem)

      描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定的设计问题,如怎样用对象表示算法等。也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模式必须满足的一系列先决条件。

3. 解决方案(solution)

      描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。

4. 效果(consequences)

      描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时,并不总提到模式效果,但它们对于评价设计选择和理解使用模式的代价及好处具有重要意义。软件效果大多关注对时间和空间的衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所以模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些效果对理解和评价这些模式很有帮助。

四、一些基本的设计模式

Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

Adapter:将一个类的接口转换成客户希望的另外一个接口。A d a p t e r模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

Bridge:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

Builder:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

Chain of Responsibility:为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

Command:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

Composite:将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

Decorator:动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。

Facade:为子系统中的一组接口提供一个一致的界面, F a c a d e模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

Factory Method:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

Flyweight:运用共享技术有效地支持大量细粒度的对象。

Interpreter:给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

Iterator:提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

Mediator:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

Memento:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

Observer:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

Prototype:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。

Proxy:为其他对象提供一个代理以控制对这个对象的访问。

Singleton:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

State:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

Strategy:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

Template Method:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

Visitor:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。


    创建型 结构型 行为型
类 Factory Method  Adapter_Class  Interpreter
Template Method 
对象 Abstract Factory
Builder
Prototype
Singleton  Adapter_Object
Bridge
Composite
Decorator
Facade
Flyweight
Proxy  Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor 
概览  


名称 Factory Method
结构 
意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
适用性 当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

名称 Abstract Factory
结构 
意图 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用性 一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当你要强调一系列相关的产品对象的设计以便进行联合使用时。
当你提供一个产品类库,而只想显示它们的接口而不是实现时。

名称 Builder
结构 
意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
当构造过程必须允许被构造的对象有不同的表示时。

名称 Prototype
结构 
意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
为了避免创建一个与产品类层次平行的工厂类层次时;或者
当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

名称 Singleton
结构 
意图 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

名称 Adapter
结构
 
意图 将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性 你想使用一个已经存在的类,而它的接口不符合你的需求
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(仅适用于对象A d a p t e r )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
 
名称 Bridge
结构 
意图 将抽象部分与它的实现部分分离,使它们都可以独立地变化。
适用性 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时B r i d g e 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
(C + +)你想对客户完全隐藏抽象的实现部分。在C + +中,类的表示在类接口中是可见的。
有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。R u m b a u g h 称这种类层次结构为“嵌套的普化”(nested generalizations )。
你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是C o p l i e n 的S t r i n g 类[ C o p 9 2 ],在这个类中多个对象可以共享同一个字符串表示(S t r i n g R e p )。
 
名称 Composite
结构 
意图 将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
适用性 你想表示对象的部分-整体层次结构。
你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
 
名称 Decorator
结构 
意图 动态地给一个对象添加一些额外的职责。就增加功能来说,D e c o r a t o r 模式相比生成子类更为灵活。
适用性 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤消的职责。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
 
名称 Facade
结构 
意图 为子系统中的一组接口提供一个一致的界面,F a c a d e 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
适用性 当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。F a c a d e 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过f a c a d e 层。
客户程序与抽象类的实现部分之间存在着很大的依赖性。引入f a c a d e 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当你需要构建一个层次结构的子系统时,使用f a c a d e 模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过f a c a d e 进行通讯,从而简化了它们之间的依赖关系。
 
名称 Flyweight
结构 
意图 运用共享技术有效地支持大量细粒度的对象。
适用性 一个应用程序使用了大量的对象。
完全由于使用大量的对象,造成很大的存储开销。
对象的大多数状态都可变为外部状态。
如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
应用程序不依赖于对象标识。由于F l y w e i g h t 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
 
名称 Proxy
结构 
意图 为其他对象提供一种代理以控制对这个对象的访问。
适用性 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用P r o x y 模式。下面是一 些可以使用P r o x y 模式常见情况:
1) 远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用N X P r o x y 类实现了这一目的。Coplien[Cop92] 称这种代理为“大使” (A m b a s s a d o r )。
2 )虚代理(Virtual Proxy )根据需要创建开销很大的对象。在动机一节描述的I m a g e P r o x y 就是这样一种代理的例子。
3) 保护代理(Protection Proxy )控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。例如,在C h o i c e s 操作系统[ C I R M 9 3 ]中K e m e l P r o x i e s 为操作系统对象提供 了访问保护。
4 )智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括:

对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为S m a r tP o i n t e r s[ E d e 9 2 ] )。
当第一次引用一个持久对象时,将它装入内存。
在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

名称 Chain of Responsibility
结构 
意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
适用性 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可处理一个请求的对象集合应被动态指定。
 
名称 Command
结构 
意图 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
适用性 像上面讨论的M e n u I t e m 对象那样,抽象出待执行的动作以参数化某对象。你可用过程语言中的回调(c a l l b a c k )函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。C o m m a n d 模式是回调机制的一个面向对象的替代品。
在不同的时刻指定、排列和执行请求。一个C o m m a n d 对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
支持取消操作。C o m m a n d 的E x c u t e 操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。C o m m a n d 接口必须添加一个U n e x e c u t e 操作,该操作取消上一次E x e c u t e 调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用U n e x e c u t e 和E x e c u t e 来实现重数不限的“取消”和“重做”。
支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。在C o m m a n d 接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用E x e c u t e 操作重新执行它们。
用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务( t r a n s a c t i o n )的信息系统中很常见。一个事务封装了对数据的一组变动。C o m m a n d 模式提供了对事务进行建模的方法。C o m m a n d 有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
 
名称 Interpreter
结构 
意图 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
适用性 当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:
该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。
效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。

名称 Iterator
结构 
意图 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
适用性 访问一个聚合对象的内容而无需暴露它的内部表示。
支持对聚合对象的多种遍历。
为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
 
名称 Mediator
结构 
意图 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
适用性 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
想定制一个分布在多个类中的行为,而又不想生成太多的子类。
 
名称 Memento
结构 
意图 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
适用性 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。
如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
 
名称 Observer
结构 
意图 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
 
名称 State
结构 
意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
适用性 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。S t a t e模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
 
名称 Strategy
结构 
意图 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适用性 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时[ H O 8 7 ] ,可以使用策略模式。
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
一个类定义了多种行为, 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的S t r a t e g y 类中以代替这些条件语句。
 
名称 Template Method
结构 
意图 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Te m p l a t e M e t h o d 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
适用性 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是O p d y k e 和J o h n s o n 所描述过的“重分解以一般化”的一个很好的例子[ O J 9 3 ]。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
控制子类扩展。模板方法只在特定点调用“h o o k ”操作(参见效果一节),这样就只允许在这些点进行扩展。
 
名称 Visitor
结构 
意图 表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
适用性 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Vi s i t o r 使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用Vi s i t o r 模式让每个应用仅包含需要用到的操作。
定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
 

五、成功采用设计模式的三个步骤

  如何把设计模式的采用和日益临近的最后期限、紧缩的预算和很多公司现有的有限团队资源相结合?以下是成功制订设计模式的三个步骤。

强大的通信和培训
  许多机构拥有领先技术,可能正式通过了设计师论坛的论证或者非正式的公认专家。这些领先厂商将推广设计模式采用中的开放通信,并将培训开发具体设计模式的团队。通信应当跨开发团队和项目以便预先防止采用竖井和多种惟一的实现(谨记每个Developer/Project AntiPattern的实现)。培训可以采用正式的internal lunch-and-learns、正式的internal class或者派一些员工参加外部培训。这些培训方式将促进正确的设计模式应用程序。如果仅有极少的观众能够参加培训,最佳的候选人是那些感觉适合在回来后能够培训其同事的人。

设计模式采用指导
  设计模式可用于使项目受益,但是他们也可能因为误用而对应用程序造成损害。应当鼓励采用他们,但是对其的采用应当受到审阅和验证。设计模式可以包含在设计和开发过程中。在任何一种情况中,设计模式的使用应当由审阅者确认和验证。在审阅过程中还可能会遇到这样的情况,额外的设计模式不适用于最初包括的地方。即使环境中没有进行正式的审阅,这一步骤也可以通过同事审阅或者团队讨论来完成。这一步骤中的审阅者要么是主要团队的成员,要么与他们建立开放通信。
  指导采用对于broad exposure类别的设计模式非常关键。这些设计模式具有很多相关的风险,因为他们将创建依赖性。这些依赖性可能在一些对象类中,例如,只工作在更加广泛的DAO设计模式实现范围中的数据访问对象(DAO)、或者跨应用程序边界(如使用Value Object设计模式在应用程序和应用程序层之间传输数据)。这些设计模式也可以由项目中的其他人或者不同项目的人实现,而且实现应当重新使用,不同于创建另一种独特的实现。

重用实现,不只是设计模式
  只要在创建自己的设计模式实现中有一定的满足,团队和公司就可以在重用发生在代码层时,而不是设计创意层时获得更多益处。使企业获益的最初设计模式是改进的实现。但是,真正的目标是重用实现。重用实现将导致:a)其他可重用的类(取决于公共实现);b)缩短开发时间和降低成本;c)缩短维护时间和降低成本;d)在应用程序之间和内部轻松集成。
  这种重用对broad exposure设计模式非常重要(有时是基本的)。这些设计模式创建了外部依赖性(集成将从公共实现中受益)或者产生全部的自定义类库(如果有公共基础将可重用)。isolated use设计模式也可以从重用中获益,但是如果他们是根据具体情况定制的,他们就非常难以重用。
  有时您可能会问自己:“如果重用比较好,为什么设计模式和可以重用的实现不可以一同应用呢?”在我们讨论设计模式如何使更多读者获益的时候才会讨论这个问题。如果可能,如果已经预定义了实现,那么达到广泛适用性这个目标就会非常困难。然而,一旦设计模式被应用到特殊的问题域或者技术基础设施中,那么就可以重用在该环境中产生的实现。

架构中的设计模式
  这看起来像是一件可怕的任务,需要掌握设计模式如何应用在实际情况中,如何构建优质的实现,以及如何促进重用实现。完成该任务的方法之一就是在环境中引入应用程序架构。应用程序架构提供了应用程序需要的结构,从而使开发团队可以关注应用程序的域逻辑。这包含了已实现的设计模式。除了重用设计模式概念或者单个实现之外,可以在多个项目和应用程序之间重用架构。这种共享的公共实现确保了兼容性,并为开发和维护多种不同的实现提供了一种低成本替代方案。兼容性提供了重新使用需要的技术基础。没有足够的篇幅在这里深入讨论架构的其他重要品质,如运行时监测和管理、可配置应用程序逻辑和适应性行为等。您可以从Carnegie Mellon Software Engineering Institute (www.sei.cmu.edu/ata/ata_init.html) 中学习到更多有关架构的知识。


 

posted @ 2008-07-31 14:33 破孩 阅读(15) | 评论 (0)编辑

来自: http://www.cnblogs.com/baiye7223725/archive/2007/07/28/834963.html

设计模式从本质上说是一种规则,从形式上说,分为创建型、结构型、行为型。

  设计模式的应用是为了实现软件设计中的几个原则,其中一个重要原则是:减少模块之间的耦合程度。为了确保这个目的,在设计一个类时,要针对接口,而非实现。(Programming to an Interface, not an Implementation)设计的时候只关心类的接口,编程的时候可以先实现一个简单的接口,供别的模块调用。使用一个类的时候只对接口工作,不关心具体的实现,也不关心具体的类型。这样也符合人类认识世界的规律,一般说来人们总是先了解一个事情的大概情况,比如,我们先了解一台电视机的大概功能,然后才能了解每个功能具体是怎样实现的。

  开始的时候不提供实现,正是为了以后能够最大限度的实现。

  设计模式不受语言的限制,使用.net或者java更容易实现。

  工厂模式(Factory)

  工厂模式属于一种创建型模式(Creational)。同样属于创建型模式的还有单件模式(Singleton),以后有机会再说。

      工厂模式的要点:

    1:存在一个创建对象的工厂;

    2:调用者从工厂中取得某些对象;

    3:由工厂决定如何创建对象;

    4:客户不知道对象是如何生成的。

  举一个例子,下面的类视图:


  Namer对象是FirstFirst和LastFirst的基类,用户调用Namer类的时候,不直接new出Namer类或者他的子类,而是使用NameFactory的getName方法得到具体的对象。这样在用户就不用关心自己正在使用的是哪一个Namer,正在调用哪一个方法。用户只针对Namer进行工作,而不用关心具体的类型。在实际工程中可以将Namer类的子类的构造函数只对NameFactory开放,进一步限制程序员。

  C#代码如下:

  1:Namer的实现

using System;

 

namespace NameFactory

{

    ///

    /// Summary description for Namer.

    ///

    //Base class for getting split names

    public class Namer {

        //parts stored here

        protected string frName, lName;

 

        //return first name

        public string getFrname(){

            return frName;

        }

        //return last name

        public string getLname() {

            return lName;

        }

    }

}

 

  2:FirstFirst类的实现

using System;

namespace NameFactory

{

    ///

    /// Summary description for FirstFirst.

    ///

    public class FirstFirst : Namer

    {

        public FirstFirst(string name)

        {

            int i = name.IndexOf (" ");

            if(i > 0) {

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

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

            }

            else {

                lName = name;

                frName = "";

            }

        }

    }

}

 

  3:LastFirst类的实现

using System;

namespace NameFactory

{

    ///

    /// Summary description for LastFirst.

    ///

    public class LastFirst : Namer

    {

        public LastFirst(string name) {

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

            if(i > 0) {

                lName = name.Substring (0, i);

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

            }

            else {

                lName = name;

                frName = "";

            }

        }

    }

}

 

  4:NameFactory,工厂的实现

using System;

namespace NameFactory

{

    ///

    /// Summary description for NameFactory.

    ///

    public class NameFactory {

        public NameFactory() {}

        public Namer getName(string name) {

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

            if(i > 0)

                return new LastFirst (name);

            else

                return new FirstFirst (name);

        }

    }

}

 

  5:调用者,一个窗体,如图:

  按钮的响应事件代码如下:

private void btCompute_Click(object sender, System.EventArgs e) {

    Namer nm = nameFact.getName (txName.Text );

    txFirst.Text = nm.getFrname ();

    txLast.Text = nm.getLname ();

}

 

  程序并不复杂,运行不运行无所谓,关键是要搞清楚Factory所起的作用:他隐藏了Namer类的创建细节,调用者始终不知道他创建的是哪一个类,也不需要关心他调用的方法是哪一个子类的。如果以后的程序的需求发生改动,比如:某国的人不仅有First Name和Last Name,还有Mid Name,就可以很方便的进行扩充,添加一个Namer的子类,修改一下Factory。调用者甚至不知道有新加了一种Namer的类型。

 

  实际的应用

 

  举一个简单的例子:工程中需要使用多种数据库,Oracle、SQL Server、Sybase,为这些数据库建立了各自的连接和查询操作的类,这些类有一个共同的基类BaseConn。可以建立一个ConnFactory类,用于根据不同情况产生具体的类。调用者不必关心自己调用的是谁。大大简化了业务代码。

 

  实际的使用例子还有很多。

 

 

  单件模式(Singleton)

  是一个非常简单的模式,这是我第一个理解并且能运用的模式。有时候模式的复杂程度并不在于本身,而是由于他的应用目的。最初的时候面对一个模式经常充满了困惑,一个简单的调用为什么要搞的如此复杂?为什么要建立这么多类,只是为了打开一个文件。

  通常说来学习一个模式是一个接受、认可、领会的过程。接受:了解模式的结构,了解实例的意义;认可:认可该模式在实际工程中的作用和可行性;领会:将模式应用到开发过程中。

  而模式的应用目的说到底无非是为了降低模块之间在时间和空间上的耦合程度,以此提高模块的复用性,降低出错的概率。

  单件模式

  Singleton模式是一个较为简单的模式,下面的代码就可以建立一个Singlton模式的例子,这是一个写系统日志的类。

public class LogWriter

{

    //申明一个静态的变量,类型为类本身

    private static LogWriter _instance = null;

 

    //将类的构造函数私有化,使得这个类不可以被外界创建

    private LogWriter()

    {

    }

 

    //提供静态的方法,创建类的实例

    public static LogWriter GetInstance()

    {

        if (_instance == null)

        {

            _instance = new LogWriter();

        }

        return _instance;

    }

 

    //下面实现类的其他功能

    //....

}

  调用者不可以通过new的形式得到Singleton的实例,调用的例子如下:

LogWriter log = LogWriter.GetInstance();

log.Debug("hello world");

 

  实际应用

  很容易想象,单件模式适用于下面的情况:整个系统中某个对象是唯一的,或者是有固定数量的。比如数据库连接,配置文件,等等……

  模式是一种程序员间的约定术语,语言可以成为思维的基础。有了这样的语言,一些复杂的概念就变得容易交流了。比如设计人员只要说到,某个类是一个单件模式,是一个Singleton,程序员听见以后就至少应该明白这个类的调用方式了,而不用再详细的说明。

posted @ 2008-07-31 10:24 破孩 阅读(14) | 评论 (0)编辑

来自:http://www.cnblogs.com/dflying/archive/2006/04/01/364458.html

English Version: http://dflying.dflying.net/1/archive/104_c_basic_interview_questions.html

如果你的简历上面写“熟悉/了解C#”,那么你就应该能够回答下面的这些基础问题。我将给出自己的简要答案以供参考。欢迎讨论。
如果是“精通”,那么请参考:http://www.cnblogs.com/dflying/archive/2006/04/01/364458.html

  1. 传入某个属性的set方法的隐含参数的名称是什么?
    value,它的类型和属性所声名的类型相同。
  2. 如何在C#中实现继承?
    在类名后加上一个冒号,再加上基类的名称。
  3. C#支持多重继承么?
    不支持。可以用接口来实现。
  4. 被protected修饰的属性/方法在何处可以访问?
    在继承或间接继承与这个类的子类中可以访问。
  5. 私有成员会被继承么?
    会,但是不能被访问。所以看上去他们似乎是不能被继承的,但实际上确实被继承了。
  6. 请描述一下修饰符protected internal
    被protected internal修饰的属性/方法只能在它的在同一个程序集(Assembly)中的子类被访问。
  7. C#提供一个默认的无参数构造函数,当我实现了另外一个有一个参数的构造函数时候,还想保留这个无参数的构造函数。这样我应该写几个构造函数?
    两个,一旦你实现了一个构造函数,C#就不会再提供默认的构造函数了,所以需要手动实现那个无参数构造函数。
  8. C#中所有对象共同的基类是什么?
    System.Object.
  9. 重载和覆写有什么区别?
    重载提供了对一个方法签名的不同参数调用的实现。覆写提供了子类中改变父类方法行为的实现。
  10. 在方法定义中,virtual有什么含意?
    被virtual修饰的方法可以被子类覆写。
  11. 能够将非静态的方法覆写成静态方法么?
    不能,覆写方法的签名必须与被覆写方法的签名保持一致,除了将virtual改为override。
  12. 可以覆写私有的虚方法么?
    不可以,甚至子类中无法访问父类中的私有方法。
  13. 能够阻止某一个类被其他类继承么?
    可以,使用关键字sealed。
  14. 能够实现允许某个类被继承,但不允许其中的某个方法被覆写么?
    可以,标记这个类为public,并标记这个方法为sealed。
  15. 什么是抽象类(abstract class)?
    一种不可以被实例化的类。抽象类中一般含有抽象方法,当然也可有具体实现。继承类只有实现过所有抽象类的抽象方法后才能被实例化。
  16. 何时必须声明一个类为抽象类?
    当这个类中包含抽象方法时,或是该类并没有完全实现父类的抽象方法时。
  17. 接口(interface)是什么?
    只含有共有抽象方法(public abstract method)的类。这些方法必须在子类中被实现。
  18. 为什么不能指定接口中方法的修饰符?
    接口中的方法用来定义对象之间通信的契约,指定接口中的方法为私有或保护没有意义。他们默认为公有方法。
  19. 可以继承多个接口么?
    当然。
  20. 那么如果这些接口中有重复的方法名称呢?
    这种情况中你可以决定如何实现。当然需要特别得小心。但是在编译环节是没有问题的。
  21. 接口和抽象类的区别是什么?
    接口中所有方法必须是抽象的,并且不能指定方法的访问修饰符。抽象类中可以有方法的实现,也可以指定方法的访问修饰符。
  22. 如何区别重载方法?
    不同的参数类型,不同的参数个数,不同的参数顺序。
  23. const和readonly有什么区别?
    const关键字用来声明编译时常量,readonly用来声明运行时常量。
  24. System.String 和System.StringBuilder有什么区别?
    System.String是不可变的字符串。System.StringBuilder存放了一个可变的字符串,并提供一些对这个字符串修改的方法。
posted @ 2008-07-30 11:34 破孩 阅读(53) | 评论 (0)编辑

 

来自:

http://www.51testing.com/?61753/action_viewspace_itemid_76398.html

C#的抽象类和方法,重载,覆盖,隐藏

2008-03-06 16:38:07 / 个人分类:编程学习

第四例 C#的抽象类和方法,重载,覆盖,隐藏

 

using System;

namespace testClassApp
{
   /// <summary>
   /// Class1 的摘要说明。
   /// </summary>
   class Class1
   {
       /// <summary>
       /// 应用程序的主入口点。
       /// </summary>
       [STAThread]
       static void Main(string[] args)
       {
          //
          // TODO: 在此处添加代码以启动应用程序
          //

          double len = 2.5;
          double wid = 3.0;
          double rad = 4.1;
          Rectangle aRect = new Rectangle();
          aRect.length = len;
          aRect.width = wid;
          Circle aCirc = new Circle (rad);
          Console.WriteLine ("Area of Rect is:{0}",aRect.Area ());
          Console.WriteLine ("Area of Circ is:{0}",aCirc.Area ());
       }
   }

   abstract class Shape             //抽象基类,不可实例化
   
/* 1)声明一个抽象类使用abstract关键字
     * 2)只要包含抽象方法的类就是抽象类(哪怕只有一个),当一个抽象类中所有的方法都是抽象时,我们就可以定义成接口
     * 一个类可以包含一个或多个抽象方法
     * 3)抽象类中可以存在非抽象的方法(方法可以有具体的实现)
     * 4)抽象类不能被实例化
     * 5)实现抽象类用":",实现抽象方法用override关键字
     * 6)抽象类可以被抽象类所继承,结果仍是抽象类
     * 7)抽象方法被实现后,不能更改修饰符
    */
    {
       public const double pi=3.14;  //常量
       protected double x, y;        //私有,可继承变量
       
//构造函数
        /*
         1)对象最初对对象进行实例化的过程叫做构造阶段,这个过程就是由构造函数完成的,构造函数就是用于初始化数据的函数。
         2)所有的对象(类)都有一个默认的构造函数,没有参数,与类同名,但一个类可以包含几个带参数的构造函数
        称为非默认的构造函数。
         3)构造函数用new关键字来调用,例如:
         * 调用默认构造函数:类名类的实例名= new 类名();
         * 调用非默认构造函数:类名类的实例名= new 类名(参数);
         * 4)构造函数与字段,属性,方法一样,可以使公共或者私有的
         * 5)构造函数只是在对象被建立时调用,就是一句代码也不写或没有实现构造函数,那么这个类也会建立,
         * 这个函数只是说在对象在建立的时候给了一个给这个对象初始设置值的机会
         */
        public Shape()               //默认构造函数
       {
          x=y=0;
       }
       public Shape(double x,double y)  //带参数构造函数
       {
          this.x = x;
          this.y = y;
       }
       public abstract double Area();   //抽象方法,需重载
        /*
         * 1)声明一个抽象方法使用abstract关键字,抽象方法只包含方法定义,但没有具体实现的方法,需要其子类或者子类的子类来具体实现
         * 2)子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。也可以不实现抽象方法,留给后代实现,
         * 这时子类仍旧是一个抽象类,必须声明为abstract
         * 3)继承的抽象方法不可以被隐藏
         */

    }

   class Rectangle: Shape
   {
       public Rectangle():base(){}
       public Rectangle(double x, double y): base(x,y){}//使用基类构造函数
       
/*
         1) 隐式调用基类构造函数:如果没有明确指明base()( 即不使用base() ),子类会自动调用基类的默认构造器
         2) 显示调用:上面的就是显示调用,使用base(参数)
         */
        public override double Area()   //函数覆盖,子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。
            //也可以不实现抽象方法,留给后代实现,
       {
          return (x*y);
       }
       public double length   //属性:矩形长度
       {
          get
          {
             return x;
          }
          set
          {
             if (value>0){x = value;}
          }
       }
       public double width    //属性:矩形宽度
       {
          get
          {
             return y;
          }
          set
          {
             if (value>0){y = value;}
          }
       }

   }

   class Ellipse: Shape
   {
       public Ellipse(double x, double y):base(x,y){}//使用基类Shape的构造函数
       public override double Area() //函数覆盖
       {
          return pi*x*y;
       }
   }
   class Circle: Ellipse
   {
       public Circle(double r):base(r,0){}  //使用基类Ellipse的构造函数
       public override double Area() //函数覆盖
       {
          return pi*x*x;
       }
   }
       
   //隐藏:在子类中创建与父类中的方法具有相同签名(相同的方法名,相同的参数列表-参数类型和次序)的方法(可以带有"virtual"或"override"关键字)即可实现,但建议使用"new"关键字,以明确地隐藏。
          //只能使用"override"关键字来覆盖(override)父类中标记为"virtual"、"abstract"或"override"的方法,而子类中标记为override的方法,也必须是父类中标记为"virtual"、"abstract"或"override"的方法。
          //覆盖(override):必须使用override关键字,可以被覆盖的方法包括标记为abstract,virtual,和override的方法;
          //隐藏:使用new关键字,也可不使用关键字,可以被隐藏的方法包括一般方法,和标记为virtual"或"override"的方法;
          //重载(overload):不需要任何特殊的关键字
          //静态方法可以被隐藏或重载
    /*重载,覆盖,隐藏之间的区别
     重载(overload)用于同一类中的成员函数,其特征为:
     * 1)在同一类中
     * 2)相同的函数名
     * 3)参数不同(包括参数类型不同,或参数个数不同,或两者都不同,注意:和返回值没关系)
     * 4)和是否虚函数无关
     覆盖(override)是指派生类函数覆盖基类函数,其特征为:
     * 1)不同的范围(分别位于派生类与基类)
     * 2)相同的函数名称
     * 3)参数相同
     * 4)基类函数必须是虚函数
     隐藏(hide)是指派生类的函数屏蔽了与其同名的基类函数,其特征为:
     * 1)不同的范围(分别位于派生类与基类)
     * 2)相同的函数名
     (3)若参数不同,基类函数无virtual关键字,基类函数将会被隐藏。(因为派生类和基类不在同一范围,所以是隐藏而不是重载);
    ()若参数不同,基类函数有virtual关键字。基类函数将会被隐藏。(因为派生类和基类不在同一范围,所以是隐藏而不是重载;因为参数不同,所以是隐藏而不是覆盖);
    ()若参数相同,基类函数无virtual关键字。基类函数将会被隐藏。(因为基类函数不是虚函数,所以是隐藏而不是覆盖)。
    ()若参数相同,基类函数有virtual关键字。如果基类函数有多个重载版本,且派生类并没有重写所有的同名虚函数,当在派生类中调用函数时,基类中未被重写的虚函数将被隐藏。(当然,被重写的函数就是覆盖了)。
注意: 如果想在派生类中调用基类中的被隐藏的函数,可以在派生类中填写如下代码:using Base::Fun2
     */


}


目前C#100例的整理进度

目前C#100例的整理进度

posted @ 2008-07-29 15:06 破孩 阅读(303) | 评论 (0)编辑

 

 

来源:

 

Beyond the dream——飛雪飄寒

 

 

今天在ZDNetChina中文社区看到一篇关于asp.net学习流程的文章,觉得写得挺不错的,于是收藏一下,相信自己每隔一段时间看一遍都会有不同的体会。信息来源:http://bbs.zdnet.com.cn/viewthread.php?tid=108315

 
     如果你已经有较多的面向对象开发经验,跳过以下这两步:

  第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET。 ASP.NET是一个全面向对象的技术,不懂OO,那绝对学不下去!

  第二步 对.NET Framework类库有一定的了解 可以通过开发Windows Form应用程序来学习.NET Framework。ASP.NET是建构在.NET Framework之上的技术,你对.NET Framework了解得越深,学习ASP.NET就越快。 举个例子:下面简单列出几个对掌握ASP.NET非常重要的概念: 对象的内存模型,委托,事件,多线程,程序集和应用程序域,安全模型 .NET Framework当然还有许多其它的东西,但不理解与把握清楚上述这些东西,是很难真正把握ASP.NET的。 出于急迫的心情与现实的考虑,不少人没有扎实的面向对象基础就想直接学习ASP.NET,其结果只能是欲速则不达。 在具备了OO基础之后,以下是具体的学习ASP.NET技术步骤。

  第一步:学习HTML与CSS
  这并不需要去学一大堆的诸如Dreamweaver,Firework之类的各种网页设计工具,关键是理解HTML网页嵌套的block结构与CSS的box模型。许多ASP.NET控件最后都必须转化为HTML。而且,div+CSS是当前主流的网页布局模型。 学习这部分时,关键在于理解概念,而不需要将精力花在美化页面的许多技巧上,那是网站美工的工作,不是程序员的工作。
 
  第二步:学习JavaScript
  JavaScript不是Java,它主要运行于浏览器端。可以完成许多工作,功能也很强大:比如它将客户端网页中的HTML元素看成一棵树,可以编写代码访问并修改树节点,动态生成新的HTML代码,从而达到动态修改网页显示特性的目的。
  JavaScript在目前的网站开发中用得很多,非常重要。
  另外,它也是目前非常流行的AJAX技术的基础。
 
  第三步:学习计算机网络原理
  找一本大学<计算机网络>教材,重点看看它的有关互联网的部分,了解一些域名解析和HTTP协议等知识。这是进行互联网开发的理论基础。

  第四步:学习ASP.NET表示层技术,会设计Web页面
  需要结合先前打好的面向对象技术的基础,至少掌握以下内容:
  (1) 各种Web控件的使用方法,
  (2) 理解信息在网页中的传送方式,比如Cookie,ViewState,Session等的使用。
  (3) ASP.NET应用程序与网页的生命周期,以及相关对象(比如httpcontext,response,request)的用途。
  (4) ASP.NET实现事件驱动的内幕
  (5) 自定义用户控件
  再次强调一下,没有OO基础,很难掌握上述技术,就只能被这些东东牵着鼻子走了,会很被动。
 
  第五步 掌握数据库技术
  具体地说,要学习以下内容:
  (1) 学会使用SQL Server 2005:不要求精通它的各种工具与管理配置技术,但至少知道如何连接,如何建表,如何创建存储过程
  (2) 学习ADO.NET,掌握使用代码人工访问数据库(别用VS2005的向导)的方法
  (3) 学习数据绑定控件的使用

  第六步 理解多层架构
  这时,先前在OO学习阶段涉及到的程序集与应用程序域等就派上用场了,现在,网站架构大多采用多层架构:表示层、业务逻辑层、数据存取层以及数据库本身。
  可以先上网找一此多层架构的资料看,再找一个现成的比较复杂的开源ASP.NET项目分析一下其架构就差不多了。基本上都是一个套路,到处应用。
  有的朋友问:学习架构是不是必须学习设计模式。
  我的看法是:不必!当然,你如果学习过设计模式,那当然更好。但在实际开发中,如果只想着机械地套用某种模式,反而起不到好的结果。我的观点:在学习设计模式时要多思多悟,其思想就会渐渐地融入你的大脑,在真实的设计实践中,忘掉所有的写在书上的模式,一切从实际出发,相信你的直觉,只要达到设计要求的方案就是可行的方案,事实上,你这样做了之后,回过头来再看,会发现你的设计往往暗合设计模式的理论。
 
  第七步 学习XML与Web Service
  先了解XML的基础知识,找本讲XML的书看一下就差不多了,然后,再学习Web Service。Web Service其实可类比为远程方法调用(以XML格式表达的调用信息)。
  学 到了这里,如果你还有兴趣,不妨再去看看SOA,不过SOA的资料都是理论与概念,看起来比较郁闷,而且离实际开发可能比较远。所以,这是可选项。

  第八步 学习AJAX
  学习AJAX的主要目的是创建具有更丰富特性的Web表示层,而经过前面七步的学习,到此再学习AJAX已水到渠成,所有的基础都已具备,不会有太大的问题了。
  在基础未具备的前提下直接学AJAX,就象“浮沙之上筑高台”,所以,将AJAX的学习次序安排在这里。
 
  第九步 学习RIA技术
  RIA:Rich internet application,可看成是将C/S与B/S优点合二为一的尝试。就具体技术来说,主要指微软的Silverlight(WPF_E),毕竟前头一路行来都是微软路线。
  不过目前学习它主要是为了技术储备。估计此技术的普及需要2到3年的时间,因为预装Vista的机器今年才开始大卖。
posted @ 2008-07-29 10:29 破孩 阅读(33) | 评论 (0)编辑

引自:http://blog.ccidnet.com/blog-htm-do-showone-uid-102484-type-blog-itemid-342579.html

http://www.cnblogs.com/tuyile006/archive/2007/03/20/681258.html

 

经典C#面试题集锦(一)

有了前面的学习和上机练习,加上一定的项目开发实践,你可以是一名合格的C#程序员。不过,如果你去应聘,各家公司的题目,有时候还有些刁钻。不一定是你不会,只不过你没有见过某些题型,一时半会可能不适应,在规定的时间内,不能完成答题。为了帮助读者渡过面试这关,我们收集了一些面试题目,帮你长见识,复习巩固知识。并在做面试题目的时候,有比较好的发挥。

1、在C#中,string str = null 与 string str = "   "有何区别?
答:string str = null 是不给他分配内存空间,而string str = "" 给它分配长度为空字符串的内存空间.
2、请简述在.net中类(class)与结构(struct)的异同。
答:Class可以被实例化,属于引用类型,是分配在内存的堆上的,Struct属于值类型,是分配在内存的栈上的。
3、C#中有没有运算符重载?能否使用指针?
答:C#中也有运算符重载,如对运算符“+”进行重载;C#中也可以使用指针,但要声明为unsafe。
4.Internal修饰符有什么含义?
答:很多C++程序员可能不太熟悉internal访问修饰符,因为C++中没有这个关键字。internal数据访问修饰符,表示对所修饰的成员在当前程序集内可以进行没有任何限制的访问;但在当前程序集外部则不能进行访问,其可访问性级别低于public ,高于protected。

5.对象能否调用静态方法
答:不能。对于类内部定义的静态变量及静态方法,该类的对象均不能调用。

6.CLR与IL分别是什么含义?
答:CLR:公共语言运行时,类似于Java中的JVM,Java虚拟机;在.net环境下,各种编程语言使用一种共同的基础资源环境,可以说,CLR就是操作系统和.net应用程序之间的支撑系统。.net应用程序的所有调用,都直接通过CLR,而不知道操作系统的存在,加强了程序代码的执行安全性。同时,操作系统也针对CLR而优化,提升了操作系统的健壮性和安全性。 还可以这样看:CLR就是具体的编程语言如C#与操作系统之间的翻译转换,同时它为具体的编程语言提供了许多资源:
?   面向对象的编程模型(继承、多态、异常处理和垃圾收集等)
?   安全模型
?   类型系统
?   所有.NET基类
?   许多.NET Framework类
? 开发、调试和评测(profiling)工具
?   执行和代码管理
?   IL到本地代码(IL-to-native)转换器和优化器
IL,中间语言,也称MSIL,微软中间语言,或CIL,通用中间语言;所有.NET源代码(不管用哪种语言编写)在进行编译时都被编译成IL。可以说是真正运行在CLR这个虚拟机上的语言,在应用程序运行时被即时(Just-In-Time,JIT)编译器处理成为机器码,被解释及执行。

7、分析以下代码,完成填空。
string strTmp = "abcdefg某某某";
int i= System.Text.Encoding.Default.GetBytes(strTmp).Length;
int j= strTmp.Length;
以上代码执行完后,i=           j=      
答:i=13,j=10。这道题,考察你是否知道汉字是由两个字节构成。

8、根据delegate的知识,完成以下用户控件中代码片段的填写。
namespace test
{
public delegate void OnDBOperate();
public class UserControlBase : System.Windows.Forms.UserControl
{
public event OnDBOperate OnNew;
private void toolBar_ButtonClick(objectsender,System.Windows.Forms.ToolBarButtonClickEventArgs e)
{
if(e.Button.Equals(BtnNew))
{
  //请在这里补齐代码用来调用OnDBOperate委托签名的OnNew事件。
}
}
}
答: if( OnNew != null ) OnNew( this, e );

 

2 .列举ASP.NET 页面之间传递值的几种方式。
答. 1).使用QueryString, 如....?id=1; response. Redirect()....
                  2).使用Session变量
                  3).使用Server.Transfer

3. 一列数的规则如下: 1、1、2、3、5、8、13、21、34...... 求第30位数是多少, 用递归算法实现。
答:public class MainClass
                  {
                  public static void Main()
                  {
                  Console.WriteLine(Foo(30));
                  }
                  public static int Foo(int i)
                  {
                  if (i <= 0)
                  return 0;
                  else if(i > 0 && i <= 2)
                  return 1;
                  else return Foo(i -1) + Foo(i - 2);
                  }
                  }

4.C#中的委托是什么?事件是不是一种委托?
答 : 委托可以把一个方法作为参数代入另一个方法。
        委托可以理解为指向一个函数的引用。
        是,是一种特殊的委托

5.override与重载的区别
答 : override 与重载的区别。重载是方法的名称相同。参数或参数类型不同,进行多次重载以适应不同的需要
        override 是进行基类中函数的重写。为了适应需要。

6.如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、Application,您有几种方法进行处理?
答 : QueryString、FormsAuthentication、 this.Server.Transfer

7.请编程遍历页面上所有TextBox控件并给它赋值为string.Empty?
答:
foreach (Control control in this.Controls)
{
if (control is TextBox)
{
TextBox tb = (TextBox)control ;
tb.Text = String.Empty ;
}
}

8.请编程实现一个冒泡排序算法?
答:
int [] array = new int [*] ;
int temp = 0 ;
for (int i = 0 ; i < array.Length - 1 ; i++)
{
for (int j = i + 1 ; j < array.Length ; j++)
{
if (array[j] < array[i])
{
temp = array[i] ;
array[i] = array[j] ;
array[j] = temp ;
}
}
}

9.描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
答:可以用任意类型。

10.求以下表达式的值,写出您想到的一种或几种实现方法: 1-2+3-4+……+m
答:
int sum=0;
bool flag=true;
for(int i=1;i<=m;i++)
{
   if(flag)
      sum+=i;
   else
      sum-=i;
   flag=!flag;
}
return sum;

12.在下面的例子里
using System;
class A
{
public A()
{
PrintFields();
}
public virtual void PrintFields(){}
}
class B:A
{
int x=1;
int y;
public B()
{
y=-1;
}
public override void PrintFields()
{
Console.WriteLine("x={0},y={1}",x,y);
}
当使用new B()创建B的实例时,产生什么输出?
答:X=1,Y=0

13.什么叫应用程序域?
答:应用程序域可以理解为一种轻量级进程。起到安全的作用。占用资源小。

14.CTS、CLS、CLR分别作何解释?
答:CTS:通用语言系统。CLS:通用语言规范。CLR:公共语言运行库。

15.什么是装箱和拆箱?
答:从值类型接口转换到引用类型装箱。从引用类型转换到值类型拆箱。

16.什么是受管制的代码?
答:unsafe:非托管代码。不经过CLR运行。

17.什么是强类型系统?
答:RTTI:类型识别系统。

18.net中读写数据库需要用到那些类?他们的作用?
答:SqlConnection/OleDbConnection:建立数据库的连接;
      SqlCommand/OleDbCommand:执行数据库脚本。


21.在.net中,配件的意思是?
答:程序集。(中间语言,源数据,资源,装配清单)

22.常用的调用WebService的方法有哪些?
答:1.使用WSDL.exe命令行工具。
     2.使用VS.NET中的Add Web Reference菜单选项

23..net Remoting 的工作原理是什么?
答:服务器端向客户端发送一个进程编号,一个程序域编号,以确定对象的位置。

 

29.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。
public void test(int i)
{
lock(this)
{
if (i>10)
{
i--;
test(i);
}
}
}
答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生)

30.简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。
答:WS主要是可利用HTTP,穿透防火墙。而Remoting可以利用TCP/IP,二进制传送提高效率。

            remoting是.net             中用来跨越machine,             process,             appdomain             进行方法调用的技术,对于三层结构的程序,就可以使用remoting技术来构建.它是分布应用的基础技术.相当于以前的DCOM            Web             Service是一种构建应用程序的普通模型,并能在所有支持internet网通讯的操作系统上实施。Web             Service令基于组件的开发和web的结合达到最佳,基于组件的对象模型  

31.公司要求开发一个继承System.Windows.Forms.ListView类的组件,要求达到以下的特殊功能:点击ListView各列列头时,能按照点击列的每行值进行重排视图中的所有行 (排序的方式如DataGrid相似)。根据您的知识,请简要谈一下您的思路
答:根据点击的列头,包该列的名称取出,按照该列名排序后,再绑定到ListView中。

32.给定以下XML文件,完成算法流程图。
<FileSystem>
< DriverC >
<Dir DirName=”MSDOS622”>
<File FileName =” Command.com” ></File>
</Dir>
<File FileName =”MSDOS.SYS” ></File>
<File FileName =” IO.SYS” ></File>
</DriverC>
</FileSystem>
请画出遍历所有文件名(FileName)的流程图(请使用递归算法)。
答:图就不画了,直接把程序写出来:
Public void DomDepthFirst(XmlNode currentNode)
{
    XmlNode node=currentNode.FirstChild;
    while(node!=null)
    {
          DomDepthFirst(node);
          node=node.NextSibling;
    }
     if(node.Name=="File")
     {
          Console.Write(((XmlElement)node).GetAttribute("FileName")+"\r\n");
     }
}


35.能用foreach遍历访问的对象需要实现 ________________接口或声明________________方法的类型。
答:IEnumerable 、 GetEnumerator。

36.GC是什么? 为什么要有GC?
答:GC是垃圾收集器。程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()

37.String s = new String("xyz");创建了几个String Object?
答:两个对象,一个是“xyx”,一个是指向“xyx”的引用对像s。

38.abstract class和interface有什么区别?
答:
声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽像类的变体。在接口中,所有方法都是抽像的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽像的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对像上调用接口的方法。由于有抽像类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

39.启动一个线程是用run()还是start()?
答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

40.接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)?
答:接口可以继承接口。抽像类可以实现(implements)接口,抽像类是否可继承实体类,但前提是实体类必须有明确的构造函数。

41.构造器Constructor是否可被override?
答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。

42.是否可以继承String类?
答:String类是final类故不可以继承。

44.两个对像值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?
答:不对,有相同的hash code。

45.swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
答:switch(expr1)中,expr1是一个整型,字符或字符串,因此可以作用在byte和long上,也可以作用在string上。

47.当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
不能,一个对象的一个synchronized方法只能由一个线程访问。

48.abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
答:都不能。

49.List, Set, Map是否继承自Collection接口?
答:List,Set是Map不是

50.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?
答:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。
equals()和==方法决定引用值是否指向同一对像equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

51.数组有没有length()这个方法? String有没有length()这个方法?
答:数组和string都没有Length()方法,只有Length属性。

52.sleep() 和 wait() 有什么区别?
答:sleep()方法是将当前线程挂起指定的时间。
wait()释放对象上的锁并阻塞当前线程,直到它重新获取该锁。

53.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
答:short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。

54.谈谈final, finally, finalize的区别。
答:
final-修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此 一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中 不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为 final的方法也同样只能使用,不能重载
finally-再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会 执行,然后控制就会进入 finally 块(如果有的话)。
finalize-方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对像从内存中清除出去之前做必要的清理 工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的 ,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对像之前对这个对象调用的。

55.如何处理几十万条并发数据?
答:用存储过程或事务。取得最大标识的时候同时更新..注意主键不是自增量方式这种方法并发的时候是不会有重复主键的..取得最大标识要有一个存储过程来获取.

56.Session有什么重大BUG,微软提出了什么方法加以解决?
答:是iis中由于有进程回收机制,系统繁忙的话Session会丢失,可以用Sate server或SQL Server数据库的方式存储Session不过这种方式比较慢,而且无法捕获Session的END事件。

57.进程和线程的区别?
答:进程是系统进行资源分配和调度的单位;线程是CPU调度和分派的单位,一个进程可以有多个线程,这些线程共享这个进程的资源。

58.堆和栈的区别?
答:栈是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小

59.成员变量和成员函数前加static的作用?
答:它们被称为常成员变量和常成员函数,又称为类成员变量和类成员函数。分别用来反映类的状态。比如类成员变量可以用来统计类实例的数量,类成员函数负责这种统计的动作。

60.ASP。NET与ASP相比,主要有哪些进步?
答:asp解释形,aspx编译型,性能提高,可以跟美工的工作分开进行,更有利于团队开发。

61.产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
int[] intArr=new int[100];
ArrayList myList=new ArrayList();
Random rnd=new Random();
while(myList.Count<100)
{
int num=rnd.Next(1,101);
if(!myList.Contains(num))
myList.Add(num);
}
for(int i=0;i<100;i++)
intArr[i]=(int)myList[i];

62.请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
答:session(viewstate) 简单,但易丢失
application 全局
cookie 简单,但可能不支持,可能被伪造
url参数 简单,显示于地址栏,长度有限
数据库 稳定,安全,但性能相对弱

63.请指出GAC的含义?
答:全局程序集缓存。

64.向服务器发送请求有几种方式?
答:get,post。get一般为链接方式,post一般为按钮方式。

65.DataReader与Dataset有什么区别?
答:一个是只能向前的只读游标,一个是内存中的表。

66.软件开发过程一般有几个阶段?每个阶段的作用?
答:需求分析,架构设计,代码编写,QA,部署

67.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指令 和语句 new 创建实例 new 隐藏基类中方法。
答:using 引入名称空间或者使用非托管资源
new 新建实例或者隐藏父类方法

68.需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.
答:string inputStr=" xx xx ";
     inputStr = Regex.Replace(inputStr.Trim(), @"\s+", " ");

69.下面这段代码输出什么?为什么?
int i=5;
int j=5;
if (Object.ReferenceEquals(i,j))
Console.WriteLine("Equal");
else
Console.WriteLine("Not Equal");
答:不相等,因为比较的是对像

70.什么叫做SQL注入,如何防止?请举例说明。
答:利用sql语言漏洞获得合法身份登陆系统。如身份验证的程序设计成:
SqlCommand com=new SqlCommand("Select * from users where username='"+t_name.text+"' and pwd='"+t_pwd.text+"'");
object obj=com.ExcuteScale();
if(obj!=null)
  {
    //通过验证
  }
这段代码容易被sql注入。如用户在t_name中随便输入,在t_pwd中输入1' and 1='1  就可以进入系统了。

71.什么是反射?
答:动态获取程序集信息

72.用Singleton如何写设计模式
答:static属性里面new ,构造函数private

73.什么是Application Pool?
答:Web应用,类似Thread Pool,提高并发性能。

74.什么是虚函数?什么是抽像函数?
答:虚函数:可由子类继承并重写的函数。抽像函数:规定其非虚子类必须实现的函数,必须被重写。

75.什么是XML?
答:XML即可扩展标记语言。eXtensible Markup Language.标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,即可以选择国际通用的标记语言,比如HTML,也可以使用象XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从SGML中简化修改出来的。它主要用到的有XML、XSL和XPath等。

77.什么是ASP.net中的用户控件?
答:用户控件一般用在内容多为静态,或者少许会改变的情况下..用的比较大..类似ASP中的include..但是功能要强大的多。

78.列举一下你所了解的XML技术及其应用
答:xml用于配置,用于保存静态数据类型.接触XML最多的是web Services..和config,soap协议

79.ADO.net中常用的对象有哪些?分别描述一下。
答:Connection 数据库连接对像
Command 数据库命令
DataReader 数据读取器
DataSet 数据集

80.什么是code-Behind技术。
答:ASPX,RESX和CS三个后缀的文件,这个就是代码分离.实现了HTML代码和服务器代码分离.方便代码编写和整理.

81.什么是SOAP,有哪些应用。
答:SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息并执行远程过程调用的协议,是一个基于XML的协议。使用SOAP,不用考虑任何特定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台上,以任何一直语言相互通信。这种相互通信采用的是XML格式的消息。

SOAP也被称作XMLP,为两个程序交换信息提供了一种标准的工作机制。在各类机构之间通过电子方式相互协作的情况下完全有必要为此制定相应的标准。

SOAP描述了把消息捆绑为XML的工作方式。它还说明了发送消息的发送方、消息的内容和地址以及发送消息的时间。SOAP是Web Service的基本通信协议。SOAP规范还定义了怎样用XML来描述程序数据(Program Data),怎样执行RPC(Remote Procedure Call)。大多数SOAP解决方案都支持RPC-style应用程序。SOAP还支持 Document-style应用程序(SOAP消息只包含XML文本信息)。

最后SOAP规范还定义了HTTP消息是怎样传输SOAP消息的。MSMQ、SMTP、TCP/IP都可以做SOAP的传输协议。  

SOAP 是一种轻量级协议,用于在分散型、分布式环境中交换结构化信息。 SOAP 利用 XML 技术定义一种可扩展的消息处理框架,它提供了一种可通过多种底层协议进行交换的消息结构。 这种框架的设计思想是要独立于任何一种特定的编程模型和其他特定实现的语义。

SOAP 定义了一种方法以便将 XML 消息从 A 点传送到 B 点。 为此,它提供了一种基于 XML 且具有以下特性的消息处理框架: 1) 可扩展, 2) 可通过多种底层网络协议使用, 3) 独立于编程模型。

82.C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
答:一个是属性,用于存取类的字段,一个是特性,用来标识类,方法等的附加性质

83.XML 与 HTML 的主要区别
答:1. XML是区分大小写字母的,HTML不区分。
2. 在HTML中,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略</p>或者</li>之类的结束 标记。在XML中,绝对不能省略掉结束标记。
3. 在XML中,拥有单个标记而没有匹配的结束标记的元素必须用一个 / 字符作为结尾。这样分析器就知道不用 查找结束标记了。
4. 在XML中,属性值必须分装在引号中。在HTML中,引号是可用可不用的。
5. 在HTML中,可以拥有不带值的属性名。在XML中,所有的属性都必须带有相应的值。

84.c#中的三元运算符是?
答:?:。

85.当整数a赋值给一个object对像时,整数a将会被?
答:装箱。

86.类成员有_____种可访问形式?
答:this.;new Class().Method;

87.public static const int A=1;这段代码有错误么?是什么?
答:const不能用static修饰。

88.float f=-123.567F; int i=(int)f;i的值现在是_____?
答:-123。

89.委托声明的关键字是______?
答:delegate.

 

91.在Asp.net中所有的自定义用户控件都必须继承自________?
答:Control。

92.在.Net中所有可序列化的类都被标记为_____?
答:[serializable]

93.在.Net托管代码中我们不用担心内存漏洞,这是因为有了______?
答:GC。

94.下面的代码中有什么错误吗?_______
using System;
class A
{
public virtual void F(){
Console.WriteLine("A.F");
}
}
abstract class B:A
{
public abstract override void F(); 答:abstract override 是不可以一起修饰.
} // new public abstract void F();

95.当类T只声明了私有实例构造函数时,则在T的程序文本外部,___可以___(可以 or 不可以)从T派生出新的类,不可以____(可以 or 不可以)直接创建T的任何实例。
答:不可以,不可以。

96.下面这段代码有错误么?
switch (i){
case(): 答://case()条件不能为空
CaseZero();
break;
case 1:
CaseOne();
break;
case 2:
dufault; 答://wrong,格式不正确
CaseTwo();
break;
}

97.在.Net中,类System.Web.UI.Page 可以被继承么?
答:可以。

98..net的错误处理机制是什么?
答:.net错误处理机制采用try->catch->finally结构,发生错误时,层层上抛,直到找到匹配的Catch为止。

99.利用operator声明且仅声明了==,有什么错误么?
答:要同时修改Equale和GetHash() ? 重载了"==" 就必须重载 "!="

 

104.某一密码仅使用K、L、M、N、O共5个字母,密码中的单词从左向右排列,密码单词必须遵循如下规则:
(1) 密码单词的最小长度是两个字母,可以相同,也可以不同
(2) K不可能是单词的第一个字母
(3) 如果L出现,则出现次数不止一次
(4) M不能使最后一个也不能是倒数第二个字母
(5) K出现,则N就一定出现
(6) O如果是最后一个字母,则L一定出现
问题一:下列哪一个字母可以放在LO中的O后面,形成一个3个字母的密码单词?
A) K B)L C) M D) N
答案:B

问题二:如果能得到的字母是K、L、M,那么能够形成的两个字母长的密码单词的总数是多少?
A)1个 B)3个 C)6个 D)9个
答案:A

问题三:下列哪一个是单词密码?
A) KLLN B) LOML C) MLLO D)NMKO
答案:C

8. 62-63=1 等式不成立,请移动一个数字(不可以移动减号和等于号),使得等式成立,如何移动?
答案:62移动成2的6次方

105.对于这样的一个枚举类型:
enum Color:byte
{
Red,
Green,
Blue,
Orange
}
答:string[] ss=Enum.GetNames(typeof(Color));
byte[] bb=Enum.GetValues(typeof(Color));

106. C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
答:attribute:自定义属性的基类;property :类中的属性

107.C#可否对内存进行直接的操作?
答:在.net下,.net引用了垃圾回收(GC)功能,它替代了程序员 不过在C#中,不能直接实现Finalize方法,而是在析构函数中调用基类的Finalize()方法

108.ADO。NET相对于ADO等主要有什么改进?
答:1:ado.net不依赖于ole db提供程序,而是使用.net托管提供的程序,2:不使用com3:不在支持动态游标和服务器端游 4:,可以断开connection而保留当前数据集可用 5:强类型转换 6:xml支持

109.写一个HTML页面,实现以下功能,左键点击页面时显示“您好”,右键点击时显示“禁止右键”。并在2分钟后自动关闭页面。
答:<script ***script>
setTimeout('window.close();',3000);
function show()
{
if (window.event.button == 1)
{
alert("左");
}
else if (window.event.button == 2)
{
alert("右");
}
}
</script>

110.大概描述一下ASP。NET服务器控件的生命周期
答:初始化 加载视图状态 处理回发数据 加载 发送回发更改通知 处理回发事件 预呈现 保存状态 呈现 处置 卸载

111.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
答:不能,可以实现接口

112.Static Nested Class 和 Inner Class的不同,说得越多越好
答:Static Nested Class是被声明为静态(static)的内部类,它可以不依赖于外部类实例被实例化。而通常的内部类需要在外部类实例化后才能实例化。

113.,&和&&的区别。
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and).

114.HashMap和Hashtable的区别。
答:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable.

115.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?
答:short s1 = 1; s1 = s1 + 1; (s1+1运算结果是int型,需要强制转换类型)
short s1 = 1; s1 += 1;(可以正确编译)

116.Overloaded的方法是否可以改变返回值的类型?
答:Overloaded的方法是可以改变返回值的类型。

117.error和exception有什么区别?
答:error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

118.<%# %> 和 <% %> 有什么区别?
答:<%# %>表示绑定的数据源
<% %>是服务器端代码块

119.你觉得ASP.NET 2.0(VS2005)和你以前使用的开发工具(.Net 1.0或其他)有什么最大的区别?你在以前的平台上使用的哪些开发思想(pattern / architecture)可以移植到ASP.NET 2.0上 (或者已经内嵌在ASP.NET 2.0中)
答:1 ASP.NET 2.0 把一些代码进行了封装打包,所以相比1.0相同功能减少了很多代码.
                  2 同时支持代码分离和页面嵌入服务器端代码两种模式,以前1.0版本,.NET提示帮助只有在分离的代码文件,无 法 在页面嵌入服务器端代码获得帮助提示,
                  3 代码和设计界面切换的时候,2.0支持光标定位.这个我比较喜欢
                  4 在绑定数据,做表的分页.UPDATE,DELETE,等操作都可以可视化操作,方便了初学者
                  5 在ASP.NET中增加了40多个新的控件,减少了工作量

120.重载与覆盖的区别?
答:1、方法的覆盖是子类和父类之间的关系,是垂直关系;方法的重载是同一个类中方法之间的关系,是水平关系
                  2、覆盖只能由一个方法,或只能由一对方法产生关系;方法的重载是多个方法之间的关系。
                  3、覆盖要求参数列表相同;重载要求参数列表不同。
                  4、覆盖关系中,调用那个方法体,是根据对象的类型(对像对应存储空间类型)来决定;重载关系,是根据调 用时的实参表与形参表来选择方法体的。

121.描述一下C#中索引器的实现过程,是否只能根据数字进行索引?
答:不是。可以用任意类型。


125.分析以下代码。
public static void test(string ConnectString)

{

System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = ConnectString;
try

{
conn.Open();
…….
}
catch(Exception Ex)
{
MessageBox.Show(Ex.ToString());
}
finally
{

if (!conn.State.Equals(ConnectionState.Closed))
conn.Close();
}
}
请问

1)以上代码可以正确使用连接池吗?

答:回答:如果传入的connectionString是一模一样的话,可以正确使用连接池。不过一模一样的意思是,连字符的空格数,顺序完全一致。

126.公司要求开发一个继承System.Windows.Forms.ListView类的组件,要求达到以下的特殊功能:点击ListView各列列头时,能按照点击列的每行值进行重排视图中的所有行 (排序的方式如DataGrid相似)。根据您的知识,请简要谈一下您的思路:
答:根据点击的列头,包该列的ID取出,按照该ID排序后,在给绑定到ListView中

127.什么是WSE?目前最新的版本是多少?
答:WSE (Web Service Extension) 包来提供最新的WEB服务安全保证,目前最新版本2.0。

128.在下面的例子里
using System;
class A
{
public A(){
PrintFields();
}
public virtual void PrintFields(){}
}
class B:A
{
int x=1;
int y;
public B(){
y=-1;
}
public override void PrintFields(){
Console.WriteLine("x={0},y={1}",x,y);
}
当使用new B()创建B的实例时,产生什么输出?
答:X=1,Y=0

129.下面的例子中

using System;
class A
{
public static int X;
static A(){
X=B.Y+1;
}
}
class B
{
public static int Y=A.X+1;
static B(){}
static void Main(){
Console.WriteLine("X={0},Y={1}",A.X,B.Y);
}
}
产生的输出结果是什么?
答:x=1,y=2

130.abstract class和interface有什么区别?
答:声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽像类的变体。在接口中,所有方法都是抽像的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽像的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对像上调用接口的方法。由于有抽像类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

posted @ 2008-07-28 11:53 破孩 阅读(107) | 评论 (0)编辑

引自:http://blog.csdn.net/alpsboy/archive/2006/09/05/1181025.aspx

相信很多刚学C#的人都对这两个概念感到迷惑,其时并不难(以前太重于技术可用性,比如:asp.net中的DataDrid怎么用等问题,没大研究过这方面),希望能对C#初学者有所帮助。请看如下代码:

class A
{...}

class B
{...}

class App
{
   
public static void Main()
   {
        A a 
= new A(); //实例化一个A的对象a
        B b = a; //把B的对象b指向a
        ......
   }
}

以上代码中的对象a没什么好说的,运行时与编译时类型均为A

而对象b的运行时类型为A,编译时类型为B

说说原因,因为对象a,b本身都是引用类型,在编译时对象b的类型由我们写的B b来确定,而在程序运行后发现b引用的内容实际是a所引用的内容,而对象a的类型是确定为A的(因已实例化了),所以b 的运行时类型就和a的类型相同了

posted @ 2008-07-24 18:04 破孩 阅读(126) | 评论 (0)编辑
引自:http://crazelionking.blogdriver.com/crazelionking/937013.html

回调函数还真有点像您随身带的BP机:告诉别人号码,在它有事情时Call您回调用于层间协作,上层将本层函数安装在下层,这个函数就是回调,而下层在一定条件下触发回调,例如作为一个驱动,是一个底层,他在收到一个数据时,除了完成本层的处理工作外,还将进行回调,将这个数据交给上层应用层来做进一步处理,这在分层的数据通信中很普遍。
其实回调和API非常接近,他们的共性都是跨层调用的函数。但区别是API是低层提供给高层的调用,一般这个函数对高层都是已知的;而回调正好相反,他是高层提供给底层的调用,对于低层他是未知的,必须由高层进行安装,这个安装函数其实就是一个低层提供的API,安装后低层不知道这个回调的名字,但它通过一个函数指针来保存这个回调,在需要调用时,只需引用这个函数指针和相关的参数指针。
其实:回调就是该函数写在高层,低层通过一个函数指针保存这个函数,在某个事件的触发下,低层通过该函数指针调用高层那个函数。
posted @ 2008-07-04 13:41 破孩 阅读(81) | 评论 (0)编辑