((Observer)stuList[i]).update(_phone);
}
}
Student.cs:
classStudent:
Observer
{
privatestring_name;
publicstringName{get{return_name;}set{_name=value;}}
privatestring_tPhone;
publicstringTPhone{get{return_tPhone;}set{_tPhone=value;}}
publicStudent(stringname){this.Name=name;this.TPhone="";}
publicvoidupdate(objecto){this.TPhone=(string)o;}
publicvoidshow()
{
Console.WriteLine("Name:
"+Name+"\nTeacher'sPhone:
"+TPhone);
}
}
第三章适配器模式
1.环境:
想使用一个已经存在的类,但它的接口不符合要求,此时用到适配器模式,将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
2.适配器模式的四种角色:
目标,被适配者,适配者,客户端
3.适配器模式分类:
类的适配器模式(采用继承实现),对象适配器(采用对象组合实现)
4.适配器模式实现步骤:
1)类适配器:
a)确定目标接口
b)确定被适配者
c)创建适配器(继承自被适配者,实现目标接口)
2)对象适配器
a)确定目标接口
b)确定被适配者
c)创建适配器(拥有被适配者的对象,实现目标接口)
5.示例:
Target.cs:
目标接口
interfaceTarget{voidrun();voidfly();}
Deer.cs:
被适配者
classDeer{
publicvoidrun(){Console.WriteLine("我是一只五彩神鹿,带你游走四处");}
}
classAdapter:
类适配器
classclassAdapter:
Deer,Target{
publicvoidfly(){Console.WriteLine("哇啊哦,我可以飞了!
");}
}
objectAdapter:
对象适配器
classobjectAdapter:
Target{
privateDeerdeer;
publicobjectAdapter(Deerd){this.deer=d;}
publicvoidrun(){deer.run();}
publicvoidfly(){Console.WriteLine("哇啊哦,我一样可以飞了!
");}
}
Program.cs:
staticvoidMain(string[]args){
TargetflyDeer=newclassAdapter();
TargetflyDeer1=newobjectAdapter(newDeer());
flyDeer.run();flyDeer.fly();flyDeer1.run();flyDeer1.fly();
System.Console.Read();
}
6.类适配器和对象适配器哪个更好:
1)类适配器采用“多继承”的实现方式,带来了不良的高耦合
2)对象适配器采用“对象组合”的方式,更符合松耦合精神
3)类适配器无法面对多个被适配对象
第四章策略模式
1.环境:
将每一个一系列的算法封装起来,而且使它们还可以相互替换,让算法独立于使用它的客户而独立变化。
2.类图:
3.三种角色:
抽象策略类,具体策略类,环境类
4.实现步骤:
1)定义抽象策略类2)实现具体策略类3)定义环境类
5.示例:
IStrategy.cs:
抽象策略类
interfaceIStrategy{voidfighting();}
Bow.cs:
具体策略类1
classBow:
IStrategy{
publicvoidfighting(){Console.WriteLine("向敌人放冷箭中…");}
}
Knife.cs:
具体策略类2
classKnife:
IStrategy{
publicvoidfighting(){Console.WriteLine("把敌人千刀万剐中…-");}
}
Cannon.cs:
具体策略类3
classCannon:
IStrategy{
publicvoidfighting(){Console.WriteLine("加农炮轰击敌人中…-");}
}
Context.cs:
环境类
classContext{
privateIStrategy_strategy;
publicContext(IStrategys){this._strategy=s;}
publicvoidfighting(){this._strategy.fighting();}
}
Program.cs:
classProgram{
staticvoidMain(string[]args){
Contextcontext;context=newContext(newKnife());
Console.WriteLine("选择武器为刀:
");context.fighting();
Console.WriteLine();context=newContext(newBow());
Console.WriteLine("选择武器为弓-:
");context.fighting();
Console.WriteLine();context=newContext(newCannon());
Console.WriteLine("选择武器为加农炮:
");context.fighting();
Console.WriteLine();Console.ReadLine();
}
}
7.策略模式的优点:
1)提供了对“开闭原则”的完美支持
2)提供了管理相关的算法族的办法
3)提供了可以替换继承关系的办法
4)可以避免使用多重条件选择语句
8.策略模式的缺点:
1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类
2)策略模式将造成产生很多策略类
9.小结:
1)如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
2)一个系统需要动态地在几种算法中选择一种。
3)不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性和安全性
第五章组合模式
1.环境:
对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行,(递归).客户端希望一致地处理容器对象和叶子对象。
2.组合模式:
描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象。
3.类图:
4.三种角色:
抽象组件类,叶子节点,组件集合类
5.实现步骤:
1)定义抽象组件接口2)实现叶子节点类,实现抽象组件类的接口
3)实现组件集合类,实现抽象组件类的接口
4)定义环境类,将叶子节点和组件集合加入根组件集合
6.示例:
Component.cs:
抽象组件接口
publicabstractclassComponent{
protectedstringname;
publicComponent(stringname){this.name=name;}
publicabstractvoidAdd(Componentc);
publicabstractvoidRemove(Componentc);
publicabstractvoidDiaplay(intdepth);
}
Doc.cs:
实现叶子节点
publicclassDoc:
Component{
publicDoc(stringname):
base(name){}
publicoverridevoidAdd(Componentc){
Console.WriteLine("不能向叶子节点添加子节点");
}
publicoverridevoidRemove(Componentc){
Console.WriteLine("叶子节点没有子节点");
}
publicoverridevoidDiaplay(intdepth){
Console.WriteLine(newstring('-',depth)+name);
}
}
File.cs:
实现组件集合类:
publicclassFiles:
Component{
Listchildren=newList();
publicFiles(stringname):
base(name){}
publicoverridevoidAdd(Componentc){this.children.Add(c);}
publicoverridevoidRemove(Componentc){this.children.Remove(c);}
publicoverridevoidDiaplay(intdepth){
Console.WriteLine(newString('-',depth)+name);
foreach(Componentcomponentinchildren){
component.Diaplay(depth+2);
}
}
}
Program.cs:
模拟用户构建文件树
classProgram{
staticvoidMain(string[]args){
FilesrootFlies=newFiles("根目录root");
rootFlies.Add(newDoc("根目录下的文件A"));
rootFlies.Add(newDoc("根目录下的文件B"));
Filescomp=newFiles("根目录下的文件夹FA");
comp.Add(newDoc("文件夹FA中的文件FAA"));
comp.Add(newDoc("文件夹FA中的文件FAB"));
rootFlies.Add(comp);
Filescomp2=newFiles("文件夹FA中的文件夹FAX");
comp2.Add(newDoc("文件夹FAX中的文件AXA"));
comp2.Add(newDoc("文件夹FAX中的文件AXB"));
comp.Add(comp2);
rootFlies.Add(newDoc("根目录下的文件C"));
DocleafD=newDoc("根目录下的文件D");
rootFlies.Add(leafD);rootFlies.Remove(leafD);rootFlies.Diaplay
(1);
Console.Read();
}
}
执行结果:
7.组合模式的优点:
1)组合模式以不遵守单一责任原则换取透明性,让Client将组合和叶节点一视同仁。
2)在实现组合模式时,有很多设计上的折衷。
要根据需求平衡透明性和安全性。
3)有时候系统需要遍历一个树枝构件的子构件很多次,这时候可以把遍历结果缓存
4)组合模式的实现中,可以让子对象持有父对象的引用进行反向追溯。
8.组合模式的缺点:
1)使用组合模式后,控制树枝构件的类型不太容易。
2)用继承的方法来增加新的行为很困难
9.小结:
组合模式使用环境
1)表示对象的部分-整体层次结构
2)用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
第六章装饰模式
1.环境:
动态的给一个对象添加一些功能,装饰模式用于动态的给一个对象添加一些额外的功能和职责
2.两种角色:
油漆工,被修饰者
3.实现方式:
实现被装饰者类;定义被装饰者对象;使用被装饰者对象产生装饰者对象
4.设计类图:
5.示例:
Car.cs:
抽象汽车类
abstractclassCar{
protectedintcost;protectedstringdescription;
publicabstractintgetCost();publicabstractstringgetDescription();
}
A1Car.cs:
classA1Car:
Car{
publicA1Car(){cost=100000;description="AudiA1Car";}
publicoverrideintgetCost(){returncost;}
publicoverridestringgetDescription(){returndescription;}
}
A4Car.cs:
classA4Car:
Car{
publicA4Car(){cost=120000;description="AudiA4Car";}
publicoverrideintgetCost(){returncost;}
publicoverridestringgetDescription(){returndescription;}
}
A6Car.cs:
classA6Car:
Car{
publicA6Car(){cost=160000;description="AudiA6Car";}
publicoverrideintgetCost(){returncost;}
publicoverridestringgetDescription(){returndescription;}
}
Decorator.cs:
classDecorator:
Car{
protectedCarc;protectedintdecoratorcost;
protectedStringdecoratordescription;
publicvoidsetCar(Cara){c=a;}
publicoverrideintgetCost(){returndecoratorcost+c.getCost();}
publicoverridestringgetDescription(){
returnc.getDescription()+decoratordescription;
}
}
Gps.cs:
具体的装饰者Gps
classGps:
Decorator{
publicGps(){decoratorcost=500;decoratordescription="withGps"}
}
Radar.cs:
具体装饰者雷达
classRadar:
Decorator{
publicRadar(){decoratorcost=1000;decoratordescription="withRadar";}
}
Program.cs:
staticvoidMain(string[]args){
A1Cara=newA1Car();
System.Console.WriteLine(a.getDescription()+"价格:
"+a.getCost());
A4Carb=newA4Car();
System.Console.WriteLine(b.getDescription()+"价格:
"+b.getCost());
Decoratordec=newGps();
dec.setCar(b);
System.Console.WriteLine(dec.getDescription()+"价格:
"+dec.getCost());
System.Console.Read();}
执行结果:
6.扩展说明:
1)装饰者与被装饰者具有相同的类型
2)可以用多个装饰者装饰一个对象
3)由于装饰者与被装饰者具有相同的类型,我们可以用装饰后的对象代替原来的对象。
4)装饰者在委派它装饰的对象作某种处理时,可以添加上自己的行为(功能扩展)(在委派之前或/和之后)。
5)对象可以在任何时候被装饰,因此我们能在运行时动态的装饰对象。
6)装饰模式解决的方案是利用子对象和委派
第七章状态模式
1.背景:
某对象发生变化时,其所能做的操作也随之变化。
状态模式解决的问题:
允许对象在其内部状态改变的时候改变它的行为
2.角色:
环境类,抽象状态类,具体状态类
3.实现步骤:
1)定义状态类接口,
2)实现Context类,具有状态的类,其中包含状态类接口的对象
3)当Context类执行某个接口的方法时,去调用真实状态类的实现方法
4)当Context类修改状态时,修改Context类的真实状态对象
4.具体实现:
Room.cs:
classRoom{
protectedStates;
publicstringgetState(){returns.getState();}
publicvoidsetState(Statea){s=a;}
publicvoidbook(){s.book();s=newBookState();}
publicvoidcheckin(){s.checkin();s=newCheckinState();}
publicvoidunbook(){s.unbook();s=newFreeState();}
publicvoidcheckout(){s.checkout();s=newFreeState();}
}
State.cs:
abstractclassState{
publicabstractstringgetState();publicabstractvoidbook();
publicabstractvoidcheckin();publicabstractvoidunbook();
publicabstractvoidcheckout();
}
FreeState.cs:
classFreeState:
State{
publicoverridestringgetState(){return"当前为空闲状态"}
publicoverridevoidbook(){
System.Console.WriteLine("当前为空闲状态,进行预定操作");