??xml version="1.0" encoding="utf-8" standalone="yes"?> JDK SRC中注解:
Z哈希表的 Map 接口的实现。此实现提供所有可选的映射操作Qƈ允许使用 null 值和 null 键。(除了不同步和允许使用 null 之外Q?tt>HashMap cM Hashtable 大致相同。)此类不保证映的序Q特别是它不保证该顺序恒久不变?
此实现假定哈希函数将元素正确分布在各桶之_可ؓ基本操作Q?tt>get ?putQ提供稳定的性能。P代集合视图所需的时间与 HashMap 实例?#8220;定w”Q桶的数量)及其大小Q键-值映关pLQ的和成比例。所以,如果q代性能很重要,则不要将初始定w讄得太高(或将加蝲因子讄得太低)?
HashMap 的实例有两个参数影响其性能Q?em>初始定w ?em>加蝲因子?em>定w 是哈希表中桶的数量,初始定w只是哈希表在创徏时的定w?em>加蝲因子 是哈希表在其定w自动增加之前可以辑ֈ多满的一U尺度。当哈希表中的条目数出了加载因子与当前定w的乘U时Q通过调用 rehash Ҏ容量翻倍?
通常Q默认加载因?(.75) 在时间和I间成本上寻求一U折街加载因子过高虽然减了I间开销Q但同时也增加了查询成本Q在大多?HashMap cȝ操作中,包括 get ?put 操作Q都反映了这一点)。在讄初始定w时应该考虑到映中所需的条目数及其加蝲因子Q以便最大限度地降低 rehash 操作ơ数。如果初始容量大于最大条目数除以加蝲因子Q则不会发生 rehash 操作?
如果很多映射关系要存储在 HashMap 实例中,则相对于按需执行自动?rehash 操作以增大表的容量来_使用_大的初始定w创徏它将使得映射关系能更有效地存储?
注意Q此实现不是同步的?/strong>如果多个U程同时讉K此映,而其中至一个线E从l构上修改了该映,则它必须 保持外部同步。(l构上的修改是指d或删除一个或多个映射关系的操作;仅改变与实例已经包含的键兌的g是结构上的修攏V)q一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在q样的对象,则应该?Collections.synchronizedMap Ҏ?#8220;包装”该映。最好在创徏时完成这一操作Q以防止Ҏ进行意外的不同步访问,如下所C: 由所有此cȝ“集合视图Ҏ”所q回的P代器都是快速失?/em> 的:在P代器创徏之后Q如果从l构上对映射q行修改Q除非通过q代器自w的 remove ?add ҎQ其他Q何时间Q何方式的修改QP代器都将抛出 ConcurrentModificationException。因此,面对q发的修改,q代器很快就会完全失败,而不冒在来不确定的旉L发生不确定行为的风险?
注意QP代器的快速失败行Z能得C证,一般来_存在不同步的q发修改Ӟ不可能作ZQ何坚决的保证。快速失败P代器最大努力抛?ConcurrentModificationException。因此,~写依赖于此异常E序的方式是错误的,正确做法是:q代器的快速失败行为应该仅用于程序错误?/em>
MVC模式是一个复杂的架构模式Q其实现也显得非常复杂。但是,我们已经l结Z很多可靠?/span>设计模式Q多U设计模式结合在一P使MVC模式的实现变得相对简单易行。Views可以看作一|Q显然可以用Composite Pattern来实现。Views和Models之间的关pd以用Observer Pattern体现。Controller控制Views的显C,可以用Strategy Pattern实现。Model通常是一个调停者,可采用Mediator Pattern来实现?/span> 现在让我们来了解一下MVC三个部分在J2EE架构中处于什么位|,q样有助于我们理解MVC模式的实现。MVC与J2EE架构的对应关pL:View处于Web Tier或者说?/span>Client TierQ通常是JSP/ServletQ即面昄部分。Controller也处于Web TierQ通常用Servlet来实玎ͼ?strong style="color: red">面昄的逻辑部分实现。Model处于Middle TierQ通常用服务端?/span>javaBean或?/span>EJB实现Q即业务逻辑部分的实?/strong>。(Enterprise Bean ?JavaBean 不同。JavaBean 是?java.beans 包开发的Q它?Java 2 标准版的一部分。JavaBean 是一台机器上同一个地址I间中运行的lg。JavaBean 是进E内lg。Enterprise Bean 是?javax.ejb 包开发的Q它是标?JDK 的扩展,?Java 2 Enterprise Edition 的一部分。Enterprise Bean 是在多台机器上跨几个地址I间q行的组件。因?Enterprise Bean 是进E间lg。JavaBean 通常用作 GUI H口部Ӟ?Enterprise Bean 则用作分布式商业对象. Q?br />
一、MVC设计思想 MVC英文即Model-View-ControllerQ即把一个应用的输入、处理、输出流E?/strong>按照Model、View、Controller的方式进行分,q样一个应用被分成三个层—?span style="color: red">模型层、视囑ֱ、控制层?/strong>
如:
class Cleanser {
private String s = new String("Cleanser");
public void append(String a) { s += a; }
public void dilute() { append(" dilute()"); }
public void apply() { append(" apply()"); }
public void scrub() { append(" scrub()"); }
public void print() { System.out.println(s); }
public static void main(String[] args) {
Cleanser x = new Cleanser();
x.dilute(); x.apply(); x.scrub();
x.print();
}
}
public class Detergent extends Cleanser {
// Change a method:
public void scrub() {
append(" Detergent.scrub()");
super.scrub(); // Call base-class version
}
// Add methods to the interface:
public void foam() { append(" foam()"); }
// Test the new class:
public static void main(String[] args) {
Detergent x = new Detergent();
x.dilute();
x.apply();
x.scrub();
x.foam();
x.print();
System.out.println("Testing base class:");
Cleanser.main(args);
}
} ///:~
可以看到基类Cleanser 中定义了scrubҎQ但zcDetergent 中对scrubҎq行了修改,q用在派生类Detergent 的scrubҎ中,要调用基本的scrubҎQ那么用super.scrub();
基类的初始化Q?/strong>
当你创徏一个派生类的对象的时候,q个对象里面q有一个基cȝ子对象,q个子对象同基类自己创徏的对象没什么两P只是从外面看来,q个子对象被包裹在派生类的对象里面?br />
基类子对象的正确初始化是非常重要的,而且只有一个办法能保证q一点:调用基类的构造函数来q行初始化,因ؓ只有它才能掌握怎么h能正地q行初始化的信息和权限。java会让zcȝ构造函数自动地调用基类的构造函数?/strong>
CZQ?br />
class Art {
Art() {
System.out.println("Art constructor");
}
}
class Drawing extends Art {
Drawing() {
System.out.println("Drawing constructor");
}
}
public class Cartoon extends Drawing {
Cartoon() {
System.out.println("Cartoon constructor");
}
public static void main(String[] args) {
Cartoon x = new Cartoon();
}
} ///:~
输出l果为:
Art constructor
Drawing constructor
Cartoon constructor
一看结果便一目了然了?br />
上面的示例是不带M参数的情况,如果构造函C带有参数的话Q那q里又要用到super的特性了。与上面super的用涵意一Psuper在这里用作:z的带参数构造函C调用基类的带参构造函敎ͼ只是q里不象上面那样super.scrub();q里只用super(i);卛_?/strong>
class Game {
Game(int i) {
System.out.println("Game constructor");
}
}
class BoardGame extends Game {
BoardGame(int i) {
super(i);
System.out.println("BoardGame constructor");
}
}
public class Chess extends BoardGame {
Chess() {
super(11);
System.out.println("Chess constructor");
}
public static void main(String[] args) {
Chess x = new Chess();
}
} ///:~
输出l果是:
Game constructor
BoardGame constructor
Chess constructor
合成和承一起用,实现cȝ复用Q?br />
class Plate {
Plate(int i) {
System.out.println("Plate constructor");
}
}
class DinnerPlate extends Plate {
DinnerPlate(int i) {
super(i);
System.out.println(
"DinnerPlate constructor");
}
}
class Utensil {
Utensil(int i) {
System.out.println("Utensil constructor");
}
}
class Spoon extends Utensil {
Spoon(int i) {
super(i);
System.out.println("Spoon constructor");
}
}
class Fork extends Utensil {
Fork(int i) {
super(i);
System.out.println("Fork constructor");
}
}
class Knife extends Utensil {
Knife(int i) {
super(i);
System.out.println("Knife constructor");
}
}
// A cultural way of doing something:
class Custom {
Custom(int i) {
System.out.println("Custom constructor");
}
}
public class PlaceSetting extends Custom {
Spoon sp;
Fork frk;
Knife kn;
DinnerPlate pl;
PlaceSetting(int i) {//把初始化工作都放在构造函C
super(i + 1);
sp = new Spoon(i + 2);
frk = new Fork(i + 3);
kn = new Knife(i + 4);
pl = new DinnerPlate(i + 5);
System.out.println(
"PlaceSetting constructor");
}
public static void main(String[] args) {
PlaceSetting x = new PlaceSetting(9);
}
} ///:~
管~译器会我们对基c进行初始化Qƈ要求我们在构建器最开头做q一工作Q但它ƈ不会监视我们是否正确初始化了成员对象。所以对此必ȝ别加以留意?/span>
FINAL关键字:
FINAL关键字指“那样东西是不允许改动”Q你可能会出于两点考虑不想让别Z改动Q?span style="color: #0000ff">设计和效率。由于这两个原因差别很大Q所以很可能会误用final关键字?br />
final的三U用途:数据QData)、方法(methodQ、类QclassQ?br />
很多语言通知~译器:“q段帔RQconstantQ数?#8221;的手Dc常量能用下列两U情况出玎ͼ
1、可以是“~译时的帔R”Q这样以后就不能改了Q?br />
2、也可以是运行时初始化的|q个g后就不想再改了?br />
如果是编译时的常量,~译器会把常量放到算式里面;q样~译的时候就能进行计,因此也就降低了运行时的开销。在Java 中这U常量必Lprimitive 型的Q而且要用final 关键词表C。这U常量的赋值必d定义的时候进行?br />
一个既是static 又是final 的数据成员会只占据一D内存,q且不可修改?br />
当final 不是指primitiveQ而是用于对象的reference 的时候,意思就有点不一样了?/span>对primitive 来说Qfinal 会将q个值定义成帔RQ但是对于对象的reference 而言Q?span style="color: #0000ff">final 的意思则是这个reference 是常量。初始化的时候,一旦将reference q到了某个对象,那么它就再也不能指别的对象了。但是这个对象本w是可以修改的;Java 没有提供某个对象作成常量的Ҏ?br />
(但是你可以自己写一个类Q这样就能把cd做常量了)
q种局限性也体现在数l上Q因为它也是一个对象?br />
注意Q通常U定Q被初始化ؓ帔R值的final static 的primitive 的名字全都用大写Q词与词之间用下
划线分开Q如VAL_ONE
Final Ҏ
使用final Ҏ的目的有?
W一QؓҎ?#8220;?#8221;Q禁止派生类q行修改。这是出于设计考虑。当你希望某个方法的功能Q能在承过E中被保留下来,q且不被覆写Q就可以使用q个Ҏ?br />
W二个原因就是效率。如果方法是final 的,那么~译器就会把调用转换?#8220;内联?inline)”。它会用Ҏ本n的拷贝来代替Ҏ的调?br />
final 和private
private Ҏ都隐含有final 的意思。由于你不能讉Kprivate 的方法,因此你也不能覆写它。你可以lprivate Ҏ加一个final 修饰W,但是q样做什么意义也没有?br />
q个问题有可能会造成混ؕQ因为即使你覆写了一个private Ҏ(它隐含有final 的意?Q看上去它还是可以运行的Q而且~译器也不会报错Q?br />
class WithFinals {
// Identical to "private" alone:
private final void f() {
System.out.println("WithFinals.f()");
}
/ / Also automatically "final":
private void g() {
System.out.println("WithFinals.g()");
}
}
class OverridingPrivate extends WithFinals {
private final void f() {
System.out.println("OverridingPrivate.f()");
}
private void g() {
System.out.println("OverridingPrivate.g()");
}
}
只有是基cL口里的东西才能被“覆写”Q如果方法是private 的,那它׃属于基类的接口。它只能是被类隐藏h的,正好有着相同的名字的代码。如果你在派生类里创Z同名的public 或protectedQ或package 权限的方法,那么它们同基cM可能同名的方法,没有M联系。你q没有覆写那个方法,你只是创Z一个新的方法。由于private Ҏ是无法访问的Q实际上是看不见的,因此q么作除了会影响cȝ代码l构Q其它什么意义都没有?br />
Final c?/span>
把整个类都定义成final ?把final 关键词放到类的定义部分的前面)q于在宣布Q你不会ȝ承这个类Q你也不允许别hȝ承这个类?/span>换言之,Zcȝ设计考虑Q它再也不需要作修改了,或者从安全角度出发Q你不希望它再生出子cR?br />
final class Dinosaur{}
注意Qfinal cȝ数据可以是final 的,也可以不是final 的,q要׃来决定。无论类是不是final 的,q一条都适用?#8220;final 用于数据?#8221;场合。但是,׃final cȝ止了l承Q覆写方法已l不可能了,?br />
此所有的Ҏ都隐含地变成final 了。你可以为final cȝҎ加一个final 修饰W,但是q一h什么意义?/span>
]]>package com.access.external;
class Soup{
private Soup(){//构造函数声明ؓprivateQ其它类不能用此构造函数创建对象;
System.out.println("sffewe");
}
public static Soup makSoup(){//其它cd通过makSoup来创建对象;
return new Soup();
}
private static Soup ps1 = new Soup();//自己创徏对象Q?br />
public static Soup access(){//q回对象的引用?br />
return ps1;
}
public void f(){}
}
class Sandwich{
void f(){
new Lunch();
}
}
public class Lunch {
void test(){
//Soup priv1 = new Soup();
Soup priv2 = Soup.makSoup();
Sandwich f1 = new Sandwich();
Soup.access().f();//不创建对象,但通过Soup中返回的对象引用调用其方法?br />
}
}
该方法返回一个句柄,它指向类Soup的一个对象?br />
Soupcd我们展示出如何通过所有构建器都设为privateQ从而防止直接创Z个类。请CQ假若不明确地至创Z个构建器Q就会自动创建默认构建器Q没有自变量Q。若自己~写默认构徏器,它就不会自动创徏。把它变成private后,没为那个类创徏一个对象。但别h怎样使用q个cdQ上面的例子为我们揭C出了两个选择。第一个选择Q我们可创徏一个staticҎQ再通过它创Z个新的SoupQ然后返回指向它的一个句柄。如果想在返回之前对Soupq行一些额外的操作Q或者想了解准备创徏多少个Soup对象Q可能是Z限制它们的个敎ͼQ这U方案无疑是特别有用的?br />
W二个选择是采?#8220;设计Ҏ”QDesign PatternQ技术,本书后面会对此进行详l介l。通常Ҏ叫作“独子”Q因为它仅允许创Z个对象。类Soup的对象被创徏成Soup的一个static private成员Q所以有一个而且只能有一个。除非通过publicҎaccess()Q否则根本无法访问它?br />
]]>
创徏面后,输入代码Q?br />
for (int i = 0; i < 10; i++) {
System.out.println(Integer.toString(i));
}
选择代码Q右键excute卛_看到l果。。很方便。。。。?br />
2、程序代码生模?br />
window->prefrences->java->editor->Templates
dQname:Sys
context:java
Description:shortcut for System.out.println
pattern:System.out.println(${cursor});
定后,在程序中输入s或Sys时再按alt+/会提C句。。。接着按enter键吧。。?br />
3、?getter ?setter Java ~辑器可以ؓ~译单元内的cd字段Q生存取元(accessorsQ也是getter和setter的method)?I. 「Source?#8594;「Generate Getter and Setter...?(或是在Java~辑器按右键Q「Source?#8594;「Generate Getter and Setter...?
挑选哪些需要徏立getter和setter的method ;
选择method要徏立的地方 ;
排序的方?
选择Access modifier ;
选择是否需要徏立批?
按OK;
4、徏立新?JAR 档案 如果要在工作C建立?JAR 档,h行下列动作: I. 在「Package Explorer」中Q可以选择性地预选一或多个要汇出?Java 元素。(在步骤IV中,q些会在JAR Package Specification_面中自动选出。) II. 从快速菜单或从菜单列的File菜单Q选取Export?III. 选取JAR fileQ然后按一下Next?br />
IV. 在JAR Package Specification面的Select the resources to export字段中,选取要汇出的资源?V. 选取适当的勾选框Q以指出想Export generated class files and resourcess或Export java source files and resources。附注:q两U情늚会汇出所选的资源?VI. 在Select the export destination字段中,输入或按一下Browse以选取 JAR 文g的位|?VII. 选取或清除Compress the contents of the JAR fileN框?VIII. 选取或清除Overwrite existing files without warningN框。如果清除这个勾选框Q则会提C确认是否要更换每一个将被改写的档案?IX. 附注Q在撰写 JAR 檔、JAR 说明?Manifest 档时Q会套用改写选项?X. 有两w择Q? 按一下Finish来立卛_?JAR 檔? 按一下NextQ用「JAR 套装选项」页面,以设定进阉项Q徏?JAR 说明Q或变更预设 manifest?br />
]]>
]]>
Map m = Collections.synchronizedMap(new HashMap(...));
Hashtable和HashMap的区别:
1.Hashtable是Dictionary的子c,HashMap是Map接口的一个实现类Q?br />
2.Hashtable
中的Ҏ是同步的Q而HashMap中的Ҏ在缺省情况下是非同步的。即是说Q在多线E应用程序中Q不用专门的操作安全地可以使用Hashtable
了;而对于HashMapQ则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解冻I
Map Collections.synchronizedMap(Map m)
q个Ҏq回一个同步的MapQ这个Map装了底层的HashMap的所有方法,使得底层的HashMap即是在多线E的环境中也是安全的?br />
3.
在HashMap中,null可以作ؓ键,q样的键只有一个;可以有一个或多个键所对应的gؓnull。当get()Ҏq回null值时Q即可以表示
HashMap中没有该键,也可以表C键所对应的gؓnull。因此,在HashMap中不能由get()Ҏ来判断HashMap中是否存在某个键Q?
而应该用containsKey()Ҏ来判断?/span>
]]>
视图(View)代表用户交互界面Q对于Web应用来说Q可以概括ؓHTML界面Q但有可能ؓXHTML?/span>XML?/span>Applet。随着应用的复杂性和规模性,界面的处理也变得h挑战性。一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流E的处理。业务流E的处理交予模型(Model)处理。比如一个订单的视图只接受来自模型的数据q显C给用户Q以及将用户界面的输入数据和h传递给控制和模型?
模型(Model)Q?/span>是业务程/状态的处理以及业务规则的制?/span>。业务流E的处理q程对其它层来说是黑操作,模型接受视图h的数据,q返回最l的处理l果?span style="color: #ff0000">业务模型的设计可以说是MVC最主要的核?/span>。目前流行的EJB模型是一个典型的?/span>用例子,它从应用技术实现的角度Ҏ型做了进一步的划分Q以便充分利用现有的lgQ但它不能作为应?/span>设计模型的框架。它仅仅告诉你按q种模型设计可以利用某些技术组Ӟ从而减了技术上的困难。对一个开发者来_可以专注于业务模型的设计?span style="color: #ff0000">MVC设计模式告诉我们Q把应用的模型按一定的规则抽取出来Q抽取的层次很重要,q也是判断开发h员是否优U的设计依据?/span>抽象与具体不能隔得太q,也不能太q。MVCq没有提供模型的设计ҎQ而只告诉你应该组l管理这些模型,以便于模型的重构和提高重用性。我们可以用对象~程来做比喻QMVC定义了一个顶U类Q告诉它的子cM只能做这些,但没法限制你能做q些。这点对~程的开发h员非帔R要?
业务模型q有一个很重要的模型那是数据模型。数据模型主要指实体对象的数?保存Q持l化Q。比如将一张订单保存到数据?/span>Q从数据库获取订单。我们可以将q个模型单独列出Q所有有x据库的操作只限制在该模型中?
控制(Controller)可以理解Z用户接收h, 模型与视图匚w在一P共同完成用户的请求?strong>划分控制层的作用也很明显Q它清楚地告诉你Q它是一个分发器Q选择什么样的模型,选择什么样的视图,可以完成什么样的用戯求?/span>控制层ƈ不做M的数据处理?/span>例如Q用LM个连接,控制层接受请求后, q不处理业务信息Q它只把用户的信息传递给模型Q告诉模型做什么,选择W合要求的视图返回给用户。因此,一个模型可能对应多个视图,一个视囑֏能对应多个模?/strong>?/span>模型、视图与控制器的分离Q得一个模型可以具有多个显C图。如果用户通过某个视图的控制器改变了模型的数据Q所有其它依赖于q些数据的视N应反映到q些变化。因此,无论何时发生了何U数据变化,控制器都会将变化通知所有的视图Q导致显C的更新。这实际上是一U模型的变化-传播机制。模型、视图、控制器三者之间的关系和各自的主要功能Q如?所C?
二、MVC设计模式的实?/strong>
ASP.NET提供了一个很好的实现q种l典设计模式的类似环境。开发者通过在ASPX面中开发用h口来实现视图Q控制器的功能在逻辑功能代码(.cs)中实玎ͼ模型通常对应应用pȝ的业务部分。在ASP.NET中实现这U设计而提供的一个多层系l,较经典的ASPl构实现的系l来说有明显的优炏V将用户昄Q视图)从动作(控制器)中分d?提高了代码的重用性。将数据Q模型)从对其操作的动作Q控制器Q分d来可以让你设计一个与后台存储数据无关的系l。就MVCl构的本质而言Q它是一U解册合pȝ问题的方法?/span>
2.1 视图
视图是模型的表示Q它提供用户交互界面。用多个包含单昄面的用户部Ӟ复杂的Web面可以展示来自多个数据源的内容Qƈ且网h员,工能独自参与这些Web面的开发和l护?/span>
在ASP.NET下,视图的实现很单。可以像开发WINDOWS界面一L接在集成开发环?/span>下通过拖动控g来完成页面开发本。本文中介绍每一个页面都采用复合视图的Ş式即Q一个页面由多个子视?用户部g)l成Q子视图可以是最单HTML 控g、服务器控g或多个控件嵌套构而成的Web自定义控件。页面都由模板定义,模板定义了页面的布局Q用户部件的标签和数目,用户指定一个模板,q_Ҏq些信息自动创徏面。针寚w态的模板内容Q如面上的站点DQ菜单,友好链接Q这些用缺省的模板内容配置Q针对动态的模板内容(主要是业务内?Q由于用Lh不同Q只能用后期绑定,q且针对用户的不同,用户部g的显C内容进行过滤。用由用户部gҎ模板配置l成的组合页面,它增Z可重用性,q原型化了站点的布局?/span>
视图部分大致处理程如下Q首先,面模板定义了页面的布局Q页面配|?/span>文g定义视图标签的具体内容(用户部gQ;然后Q由面布局{略cd始化q加载页面;每个用户部gҎ它自q配置q行初始化,加蝲校验器ƈ讄参数Q以及事件的委托{;用户提交后,通过了表C层的校验,用户部g把数据自动提交给业务实体x型?/span>
q一部分主要定义了WEB面基类PageBaseQ页面布局{略cPageLayoutQ完成页面布局Q用于加载用户部件到面Q用户部件基cUserControlBase即用户部件框Ӟ用于动态加载检验部Ӟ以及实现用户部g的个性化。ؓ了实现WEB应用的灵zL,视图部分也用C许多配置文g例如Q置文g有模杉K|、页面配|、\径配|、验证配|等?/span>
2.2 控制?/span>
Z能够控制和协调每个用戯多个请求的处理Q控制机制应该以集中的方式进行管理。因此,Z辑ֈ集中理的目的引入了控制器。应用程序的控制器集中从客户?/span>接收hQ典型情况下是一个运行浏览器的用PQ决定执行什么商业逻辑功能Q然后将产生下一步用L面的责Q委派l一个适当的视囄件?/span>
用控制器提供一个控制和处理h的集中入口点Q它负责接收、截取ƈ处理用户hQƈ请求委托给分发者类Q根据当前状态和业务操作的结果决定向客户呈现的视图。在q一部分主要定义了HttpReqDispatcher(分发者类)、HttpCapture(h捕获者类)、Controller(控制器类){,它们怺配合来完成控制器的功能。请求捕莯类捕获HTTPhq{发给控制器类。控制器cLpȝ中处理所有请求的最初入口点。控制器完成一些必要的处理后把h委托l分发者类Q分发者类分发者负责视囄理和导航,它管理将选择哪个视图提供l用Pq提供给分发资源控制。在q一部分分别采用了分发者、策略、工厂方法、适配器等设计模式?/span>
Z使请求捕莯类自动捕获用户hq进行处理,ASP.NET 提供低别的h/响应 APIQ开发h员能够?.NET 框架cMؓ传入?HTTP h提供服务。ؓ此,必须创作支持 System.Web.IHTTPHandler 接口和实?ProcessRequest() Ҏ的类卻Ih捕获者类Qƈ在web.config ?QhttphandlersQ?节中dcRASP.NET 收到的每个传?HTTP h最l由实现 IHTTPHandler 的类的特定实例来处理。IHttpHandlerFactory 提供了处?IHttpHandler 实例 URL h的实际解析的l构。HTTP 处理E序和工厂在 ASP.NET 配置中声明ؓ web.config 文g的一部分。ASP.NET 定义了一?QhttphandlersQ?配置节,在其中可以添加和U除处理E序和工厂。子目录l承 HttpHandlerFactory ?HttpHandler 的设|?HTTP 处理E序和工厂是 ASP.NET |架的M。工厂将每个h分配l一个处理程序,后者处理该h?例如Q在全局 machine.config 文g中,ASP.NET 所有对 ASPx 文g的请求映到 HttpCapturec:
QhttphandlersQ?br />
...
...
Q?httphandlersQ?/span>
2.3 模型
MVCpȝ中的模型从概念上可以分ؓ两类――系l的内部状态和改变pȝ状态的动作。模型是你所有的商业逻辑代码片段所在。本文ؓ模型提供了业务实体对象和业务处理对象Q所有的业务处理对象都是从ProcessBasecL生的子类。业务处理对象封装了具体的处理逻辑Q调用业务逻辑模型Qƈ且把响应提交到合适的视图lg以生响应。业务实体对象可以通过定义属性描q客L表单数据。所有业务实体对象都EntityBasez子类对象Q业务处理对象可以直接对它进行读写,而不再需要和request、response对象q行数据交互。通过业务实体对象实现了对视图和模型之间交互的支持。实现时?做什?Q业务处理)?如何?Q业务实体)分离。这样可以实C务逻辑的重用。由于各个应用的具体业务是不同的Q这里不再列丑օ具体代码实例?/span>
三、MVC设计模式的扩?/strong>
通过在ASP.NET中的MVC模式~写的,h极其良好的可扩展性。它可以L实现以下功能Q?/span>
①实C个模型的多个视图Q?/span>
②采用多个控制器Q?/span>
③当模型改变Ӟ所有视囑ְ自动hQ?/span>
④所有的控制器将怺独立工作?/span>
q就是MVC模式的好处,只需在以前的E序上稍作修Ҏ增加新的c,卛_L增加许多E序功能。以前开发的许多cd以重用,而程序结构根本不再需要改变,各类之间怺独立Q便于团体开发,提高开发效率。下面讨论如何实C个模型、两个视囑֒一个控制器的程序。其中模型类及视囄Ҏ不需要改变,与前面的完全一Pq就?/span>面向对象~程的好处。对于控制器中的c,只需要增加另一个视图,q与模型发生兌卛_。该模式下视图、控制器、模型三者之间的C意囑֦?所C?br />
四、MVC的优?/strong>
大部分用q程语言比如ASP?/span>PHP开发出来的Web应用Q初始的开发模板就是合层的数据编E。例如,直接向数据库发送请求ƈ用HTML昄,开发速度往往比较?但由于数据页面的分离不是很直?因而很难体现出业务模型的样子或者模型的重用性。品设计弹性力度很,很难满用户的变化?/span>需?/span>。MVC要求对应?/span>分层Q虽然要p额外的工作,但品的l构清晰Q品的应用通过模型可以得到更好C现?
首先Q最重要的是应该有多个视囑֯应一个模型的能力。在目前用户需求的快速变化下Q可能有多种方式讉K应用的要求。例如,订单模型可能有本pȝ的订单,也有|上订单Q或者其他系l的订单Q但对于订单的处理都是一P也就是说订单的处理是一致的。按MVC设计模式Q一个订单模型以及多个视囑֍可解决问题。这样减了代码的复Ӟ卛_了代码的维护量Q一旦模型发生改变,也易于维护?其次Q由于模型返回的数据不带M昄格式Q因而这些模型也可直接应用于接口的用?
再次Q由于一个应用被分离Z层,因此有时改变其中的一层就能满_用的改变。一个应用的业务程或者业务规则的改变只需改动MVC的模型层?
控制层的概念也很有效Q由于它把不同的模型和不同的视图l合在一起完成不同的hQ因此,控制层可以说是包含了用户h权限的概c?
最后,它还有利?/span>软g工程化管理。由于不同的层各司其职,每一层不同的应用h某些相同的特征,有利于通过工程化、工具化产生理E序代码?/span>
五、MVC的不?/strong>
MVC的不体现在以下几个斚wQ?/span>
Q?Q增加了pȝl构和实现的复杂性。对于简单的界面Q严格遵循MVCQ模型、视图与控制器分,会增加结构的复杂性,q可能生过多的更新操作Q降低运行效率?/span>
Q?Q视图与控制器间的过于紧密的q接。视图与控制器是怺分离Q但实联系紧密的部Ӟ视图没有控制器的存在Q其应用是很有限的,反之亦然Q这样就妨碍了他们的独立重用?/span>
Q?Q视囑֯模型数据的低效率讉K。依据模型操作接口的不同Q视囑֏能需要多ơ调用才能获得够的昄数据。对未变化数据的不必要的频繁讉KQ也损x作性能?/span>
Q?Q?目前Q一般高U的界面工具或构造器不支持MVC模式。改造这些工具以适应MVC需要和建立分离的部件的代h是很高的Q从而造成使用MVC的困难?/span>
构造函数重载:重蝲三要素(参数数量、参数类型、参数的排列序Q?br /> 基本数据cd的重载:如果实参比Ş参的cd,数据会先提升Q如果实参比形参大,那么要先q行强制cd转换?br /> q回值类型不是重载的要素Q?/strong>理解之一是,构造函数要实现重蝲Q但构造函数无q回倹{另外调用函数的时候可以没有返回值类型?/span>
this关键词的使用Q?/span>
1、this只能用于Ҏ内部Q它负责q回调用q个Ҏ的对象的引用。你可以把this对象的引用当成Q何对象的引用?/span>
2、this用于在构造函C调用其他构造函敎ͼ但只能调用一个,且调用的代码应放在程序最前面Q否则编译器会报错?/span>
3、this.s=s当类的数据成员与cȝҎ的参数同名时Q用this.s=s消除歧义?/span>
static的含义:
它的意思是Q这个方法没有thisQ你不能在staticҎ里调用非static的方法,但你却可以不通过对象Q直接调用staticҎ。类的staticҎ只能讉K其它staticҎstatic成员?br />Tag(int marker){输出l果为:
System.out.println("Tag("+marker+")");
}
}
class Card{
Tag t1 = new Tag(1);
Card(){
System.out.println("Card()");
t3 = new Tag(22);
}
Tag t2 = new Tag(2);
void f(){
System.out.println("f()");
}
Tag t3 = new Tag(3);
}
public class Clean {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Card t = new Card();
t.f();
}
}
Tag(1)
Tag(2)
Tag(3)
Card()
Tag(22)
f()
Q?br /> 4、l执行new Cupboard();Q注意初始化的顺序是static初始?>非static初始?>执行构造函敎ͼ所以加载类Cupboard后,首先LCupboardcM的static代码D?/span>Q?/strong>package com.initialization.order;
class Bowl {
Bowl(){
System.out.println("Bowl(9)");
}
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
static Bowl b6 = new Bowl(6);
static Bowl b9 = new Bowl();
void f(int marker) {
System.out.println("f(" + marker + ")");
}
}class Table {
static Bowl b1 = new Bowl(1);
Table() {
System.out.println("Table()");
b2.f(1);
}
void f2(int marker) {
System.out.println("f2(" + marker + ")");
}
static Bowl b2 = new Bowl(2);
}
class Cupboard {
Bowl b3 = new Bowl(3);
Bowl b10 = new Bowl();
static Bowl b4 = new Bowl(4);
Cupboard() {
System.out.println("Cupboard()");
b4.f(2);
}
void f3(int marker) {
System.out.println("f3(" + marker + ")");
}
static Bowl b5 = new Bowl(5);
}public class StaticInitialization {
//static Bowl b7 = new Bowl(7); //----------(1)
public static void main(String[] args) {
System.out.println(
"Creating new Cupboard() in main");
new Cupboard();
System.out.println(
"Creating new Cupboard() in main");
new Cupboard();
//t2.f2(1); //--------------(2)
//t3.f3(1); //---------------(3)
}
//static Bowl b8 = new Bowl(8); //----------------(4)
//static Table t2 = new Table(); //----------------(5)
//static Cupboard t3 = new Cupboard(); //---------(6)
} ///:~
调试以上代码QȝZ下结论:
一、初始化的过E:M来说序为:static初始?>非static初始?>执行构造函敎ͼ
二、代码分析一Q对现有代码执行l果如下Q?br />
Creating new Cupboard() in main
Bowl(6)
Bowl(9)
Bowl(4)
Bowl(5)
Bowl(3)
Bowl(9)
Cupboard()
f(2)
Creating new Cupboard() in main
Bowl(3)
Bowl(9)
Cupboard()
f(2)
执行q程Q?br /> 1、java解释器寻找public classc,加蝲StaticInitialization c;
2、寻找StaticInitialization cM的static定义代码D;q里因ؓ(1)?4)?5)?6)均加了注释,所以StaticInitialization 中没有static需要初始化;3、进入main函数中执行代码输?span style="color: #ff0000">Creating new Cupboard() in main
ȝ如下Q?/span>初始化顺序ؓQ加载public StaticInitializationc?>初始化static->加蝲cCupboard->初始化static->加蝲cBowl->初始化static->执行BowlcL造函?>初始化Cupboardc非static->调用BowlcL造函数执?>调用CupboardcL造函数执?>q回StaticInitializationc?