软件设计模式经典案例个人经验总结.docx
- 文档编号:30089171
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:19
- 大小:207.81KB
软件设计模式经典案例个人经验总结.docx
《软件设计模式经典案例个人经验总结.docx》由会员分享,可在线阅读,更多相关《软件设计模式经典案例个人经验总结.docx(19页珍藏版)》请在冰豆网上搜索。
软件设计模式经典案例个人经验总结
DesignPatternsds
●为软件系统的子系统、组件或者组件之间的关系提供一个精炼之后的解决方案
●它描述了在特定环境下,用于解决通用软件设计问题的组件以及这些组件相互通信时的可重现结构
-creationalpattern
抽象了实例化过程,帮助一个系统独立于如何创建、组合和表示它的那些对象。
一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象
-structuralpattern
涉及到如何组合类和对象以获得更大的结构。
结构型类模式使用继承机制来组合接口和实现。
结构型对象模式描述了如何对一些对象进行组合,从而实现新功能的一些方法。
-behavioralpattern
涉及到算法和对象间职责的分配。
不仅描述对象或类的模式还描述他们之间的通信模式。
行为类模式使用继承机制在类间分配行为。
行为对象模式使用对象复合而不是继承。
(1)Templatemethod(模板方法):
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
这里的算法的结构,可以理解为你根据需求设计出来的业务流程。
特定的步骤就是指那些可能在内容上存在变数的环节。
1)AbstractClass(抽象类):
定义了一到多个的抽象方法,以供具体的子类来实现它们;而且还要实现一个模板方法,来定义一个算法的骨架。
该模板方法不仅调用前面的抽象方法,也可以调用其他的操作,只要能完成自身的使命。
2)ConcreteClass(具体类):
实现父类中的抽象方法以完成算法中与特定子类相关的步骤。
(2)Façade(外观模式):
外观模式(Facadepattern)为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度和依赖。
这使得子系统更易于使用和管理。
外观是一个能为子系统和客户提供简单接口的类。
当正确的应用外观,客户不再直接和子系统中的类交互,而是与外观交互。
外观承担与子系统中类交互的责任。
实际上,外观是子系统与客户的接口,这样外观模式降低了子系统和客户的耦合度(Figure2).
从图中我们可以看到:
外观对象隔离了客户和子系统对象,从而降低了耦合度。
当子系统中的类进行改变时,客户端不会像以前一样受到影响。
(3)Proxy(代理模式):
它建议创建那些占用大量内存或处理复杂的对象时,把创建这类对象推迟到使用它的时候。
这时,需要设计一个与真实对象具有相同接口的单独对象(指虚拟代理)。
不同的客户对象在创建和使用真实对象地方用相应的虚拟对象来代替。
虚拟对象把真实对象的引用作为它的属性变量。
代理对象不会自动创建真实对象,当客户需要真实对象的服务时,调用虚拟代理对象上的方法,并且检测真实对象是否被创建。
如果真实对象已经创建,代理把调用转发给真实对象,如果真实对象没有被创建:
1)代理对象创建真实对象
2)代理对象把这个对象分配给引用变量。
3)代理把调用转发给真实对象
publicabstractclassIDEOperation{//功能类的抽象父类
privateCompilercmp;
privateRuntimertime;
publicIDEOperation(){
cmp=newCompiler();
rtime=newRuntime();
}
publicvoidcompile(StringjavaFile){
pile(javaFile);
}
publicvoidrun(StringclassFile){
rtime.run(classFile);
}//该方法会等到子类去实现
publicabstractvoidgenerateDocs(StringjavaFile);
}
publicclassRealProcessorextendsIDEOperation{//功能类实现父类
JavaDocjdoc;
publicRealProcessor(){
super();
jdoc=newJavaDoc();
}
publicvoidgenerateDocs(StringjavaFile){//实现父类中的方法
jdoc.generateDocs(javaFile);
}
}
publicclassProxyProcessorextendsIDEOperation{//代理功能类,继承同一个父类(相同接口)
privateRealProcessorrealProcessor;//真实功能类的一个对象引用。
publicvoidgenerateDocs(StringjavaFile){//用户调用代理类的此方法
if(realProcessor==null){
realProcessor=newRealProcessor();
}
realProcessor.generateDocs(javaFile);
}
}
publicclassClient{//客户程序
publicstaticvoidmain(String[]args){
IDEOperationIDE=newProxyProcessor();//客户使用代理类
IDE.compile("test.java");
IDE.run("test.class");
IDE.generateDocs("test.java");//客户对象像调用真实处理对象一样调用
ProxyProcessor上的方法,并不需要关心(知道)RealProcessor对象是否存在。
客户对象像调用真实处理对象一样调用ProxyProcessor上的方法,并不需要关心(知道)RealProcessor对象是否存在。
}
}
(4)Decorator(装饰器模式)
使用场景:
动态的给一个对象添加额外的职责
1、装饰器模式主要装饰供外部调用的接口方法,如果一个接口方法只是提供给内部调用,则不能使用该模式。
2、装饰器模式主要装饰可能要改变的接口方法,如果类中的某种行为在将来可能发生变化,而你又懒得去改变原来的类,那么就可以考虑使用装饰器模式了。
//接口或者抽象基类
publicinterfaceIDecorate
{
publicvoidsayHello();
}
//被装饰对象,实现了前面提到的接口或者抽象基类的实现类。
publicclassDecorateImplimplementsIDecorate
{
publicvoidsayHello()
{
System.out.print("Hello");
}
}
//装饰对象,就是去装饰被装饰对象的对象。
和被装饰对象继承同一个父类。
publicclassDecorateimplementsIDecorate
{
//声明一个被装饰的对象
privateIDecoratedecorate;
//被装饰对象从装饰器的构造函数中传进来(必须这样做)
publicDecorate(IDecoratedecorate)
{
this.decorate=decorate;
}
//在基类装饰器中只调用被装饰对象的方法
publicvoidsayHello()
{
decorate.sayHello();
}
}
//继承装饰对象类的子类,也就是具体的装饰器类了
publicclassSimpleDecorateextendsDecorate
{
publicSimpleDecorate(IDecoratedecorate)
{
super(decorate);
}
//开装饰了哦。
。
。
publicvoidsayHello()
{
//在原来的方法中加入了sayChina方法。
sayChina();
super.sayHello();
//在原来的方法中加入了sayWorld方法。
sayWorld();
}
publicvoidsayChina()
{
System.out.print("China,");
}
publicvoidsayWorld()
{
System.out.print("World!
\n");
}
}
//来,测试一下
publicvoidTestDecorate()
{
//使用装饰器
publicstaticvoiduseDecorate(IDecoratedecorate)
{
IDecoratesimpleDecorate=newSimpleDecorate(decorate);
//要调用装饰了的方法
//输出China,HelloWorld!
simpleDecorate.sayHello();
}
(5)Bridge(桥模式):
桥梁模式的用意是将问题的抽象和实现分离开来实现,通过用聚合代替继承来解决子类爆炸性增长的问题。
比如我们有一个画图程序有2个图形(Circle,Rectangle)和2种画图方法(Drawing1,Drawing2)图形可能会使用Drawing1来画图也可能使用Drawing2来画图。
在这个画图程序中有两个可变因素一个是图形的种类有可能会增加新的图形另一个是画图方法可能会有Drawing3出现
当系统有两个可变因素时我就应该考虑到桥梁模式,至少它应该在你的脑子里闪过
在面向对象设计中有两条重要原则
1.找出变化并封装之
2.优先使用聚合而不是继承
在上例中图形是一个变化我们可以抽象出一个形状接口和一些形状类
1.interface Shape{
2. void doDraw();
3.}
4.class Circle implements Shape{}
5.class Rectangle implements Shape{}
interfaceShape{
voiddoDraw();
}
classCircleimplementsShape{}
classRectangleimplementsShape{}
画图方法也可以抽象出一个Drawing接口和各种画法
1.interface Drawing{
2. void draw();
3.}
4.class Drawing1 implements Drawing{}
5.class Drawing2 implements Drawing{}
interfaceDrawing{
voiddraw();
}
classDrawing1implementsDrawing{}
classDrawing2implementsDrawing{}
最后将两个变化联系起来
在问题域中是图形使用画图方法所有应该在Shape中使用Drawing
我们可以通过在具体的图形类中通过构造函数传入具体的画图方法来实现
如下
1.class Circle implements Shape{
2. private Drawing drawing; //组合要调用的类
3. public Circle(Drawing drawing){
4. this.drawing = drawing;
5. }
6.
7. public void doDrow(){
8. drawing.draw();
9. }
10.}
11.
12.class Client(){
13. public static void main(String[] args){
14. Shape circle = new Circle(new Drawing2());
15. circle.draw();
16. }
17.}
(6)Factorymethod(工厂方法模式):
定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。
核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
抽象工厂(Creator)角色:
任何在模式中创建的对象的工厂类必须实现这个接口。
AbstractFactory
具体工厂(ConcreteCreator)角色:
这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
FactoryA,FactoryB……
抽象产品(Product)角色:
工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
Plant,Fruit
具体产品(ConcreteProduct)角色:
这个角色实现了抽象产品角色所定义的接口。
某具体产品有专门的具体工厂创建,它们之间往往一一对应。
PlantA,PlantB,FruitA,FruitB……
(7)组合模式(CompositePattern)
●定义
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
●组合模式(CompositePattern)结构图
Component为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。
声明一个接口用于访问和管理Component的子部件
abstractclassComponent
{
protectedstringname;
publicComponent(stringname)
{
this.name=name;
}
publicabstractvoidAdd(componentc);//通常都用Add和Remove方法来提供增加或移出树叶或树枝的功能
publicabstractvoidRemove(Componentc);
publicabstractvoidDisplay(indepth);
}
Leaf在组合中表示叶节点对象,叶节点没有子节点
classLeafextendsComponent
{
publicLeaf(stringname):
base(name)
{}
publicoverridevoidAdd(Componentc)//由于叶节点没有再增加分枝和树叶,所以Add和Remove方法实现
{
Console.WriteLine("Cannotaddtoaleaf");
}
publicoverridevoidRemove(Componentc)
{
Console.WriteLine("Cannotremovetoaleaf");
}
publicoverridevoidDisplay(intdepth)
{
//叶节点的具体方法,此处是显示其名称和级别
Console.WriteLine();
}
}
Composite定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关的操作,比如增加Add和删除Remove
classCompositeextendsComponent
{
privateList
publicComposite(stringname):
base(name)
{}
publicoverridevoidAdd(Componentc)
{
children.add(c);
}
publicoverridevoidRemove(Componentc)
{
children.Remove(c);
}
publicoverridevoidDisplay(intdepth)
{//显示枝节点名称,并对其下级进行遍历
Console.WriteLine(newstring('-',depth)+name);
foreach(Componentcomponentinchildren)
{
component.Display(depth+2);
}
}
}
客户端代码,能通过Component接口操作组合部件的对象
staticvoidMain(string[]args)
{
Componentroot=newComponent("root");
root.Add(newLeaf("LeafA"));//生成树根root,根上长出两叶
root.Add(newLeaf("LeafB"));//LeafA与LeafB
Compositecomp=newComposite("ComponsiteX");
comp.Add(newLeaf("LeafXA"));
comp.Add(newLeaf("LeafXB"));
root.Add(comp);
Compositecomp2=newComposite("CompositeXY");
comp2.Add(newLeaf("LeafXYA"));
comp2.Add(newLeaf("LeafXYB"));
comp.Add(comp2);
//根部又长出两页LeafC和LeafD,可惜LeafD没有长牢,被风吹走了
root.Add(newLeaf("Leafc"));
Leafleaf=newLeaf("LeafD");
root.Add(leaf);
root.Remove(leaf);
root,Display
(1);//显示大树的样子
}
显示结果:
-root
---leafA
---leafB
---CompositeX
-----LeafXA
-----LeafXB
-----CompositeXY
-------CompositeXYA
-------CompositeXYB
---Leafc
●适用场景
当需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同时,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了
●组合模式的优点:
组合模式定义了包含基本对象和组合对象的类层次结构。
基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就是用不着为定义组合而写一些选择判断语句了,简单地说就是组合模式让客户可以一致地使用组合结构和单个对象。
透明方式:
也就是说在Component中声明所有用来管理子对象的方法中,其中包括Add、Remove等。
这样实现Component接口的所有子类都具备了Add和Remove。
这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。
但问题也很明显,因为Leaf类本身不具备Add()、Remove()方法的功能,所以实现它是没有意义的。
安全方式:
也就是在Component接口中不去声明Add和Remove方法,那么子类的Leaf也不需要去实现它,而是在Composite声明所有用来管理子类对象的方法。
不过由于不透明,所以树叶和树枝将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。
classCircleimplementsShape{
privateDrawingdrawing;
publicCircle(Drawingdrawing){
this.drawing=drawing;
}
publicvoiddoDrow(){
drawing.draw();
}
}
classClient(){
publicstaticvoidmain(String[]args){
Shapecircle=newCircle(newDrawing2());
circle.draw();
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件设计 模式 经典 案例 个人 经验总结