




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、开闭原则开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。 import java.lang.*; interface Fruit public void plant(); public void blossom(); public void outcome(); class Apple implements Fruit Apple()this.plant(); public void plant()System.out.println("Plant a apple"); p
2、ublic void blossom()System.out.println("Apple blossomed"); public void outcome()System.out.println("Apple outcomed"); class Pear implements Fruit Pear()this.plant(); public void plant()System.out.println("Pear a apple"); public void blossom()System.out.println("Pea
3、r blossomed"); public void outcome()System.out.println("Pear outcomed"); interface gardenerBase /Garden,是不能改变的.以后增加一个水果只需要 再写个类继承它! public Fruit getFruit(); class AppleGardener implements gardenerBase/种植Apple的Garden private static AppleGardener singleton; private AppleGardener(); publ
4、ic static AppleGardener getGardener() if(singleton=null) singleton = new AppleGardener(); return singleton; public Fruit getFruit() return new Apple(); class PearGardener implements gardenerBase/种植Pear的Garden private static PearGardener singleton; private PearGardener(); public static PearGardener g
5、etGardener() if(singleton=null) singleton = new PearGardener(); return singleton; public Fruit getFruit() return new Pear(); public class MyFirstOCPJAVA public static void main(String a) Fruit tempApple; gardenerBase appleGarden = AppleGardener.getGardener(); tempApple = appleGarden.getFruit(); Frui
6、t tempPear; gardenerBase pearGarden = PearGardener.getGardener(); tempPear = pearGarden.getFruit(); 里氏代换原则一个软件实体如果使用的是一个基类的话,那么一定适用于其子类。而且它觉察不出基类对象和子类对象的区别。也就是说,在软件里面,把基类都替换成它的子类,程序的行为没有变化。反过来的代换不成立,如果一个软件实体使用的是一个子类的话,那么它不一定适用于基类。里氏代换原则的四层含义1)子类必须完全实现父类的方法。在类中调用其他类是务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背
7、了LSP原则。2)子类可以有自己的个性。子类当然可以有自己的行为和外观了,也就是方法和属性3)覆盖或实现父类的方法时输入参数可以被放大。即子类可以重载父类的方法,但输入参数应比父类方法中的大,这样在子类代替父类的时候,调用的仍然是父类的方法。即以子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松。4)覆盖或实现父类的方法时输出结果可以被缩小。4、里氏代换原则在设计模式中的体现 策略模式(Strategy) 如果有一组算法,那么就将算法封装起来,使得它们可以互换。客户端依赖于基类类型,而变量的真实类型则是具体策略类。这是具体策略焦色可以“即插即用”的关键。 合成模式(Compo
8、site) 合成模式通过使用树结构描述整体与部分的关系,从而可以将单纯元素与符合元素同等看待。由于单纯元素和符合元素都是抽象元素角色的子类,因此两者都可以替代抽象元素出现在任何地方。里氏代换原则是合成模式能够成立的基础。 代理模式(Proxy) 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。代理模式能够成立的关键,就在于代理模式与真实主题模式都是抽象主题角色的子类。客户端只知道抽象主题,而代理主题可以替代抽象主题出现在任何需要的地方,而将真实主题隐藏在幕后。里氏代换原则是代理模式能够成立的基础。public interface Quadrangle public lon
9、g getWidth() ; public long getHeight() ;public class Rectangle implements Quadrangle private long width ; private long height ; public void setWidth(long width) this.width = width ; public void setHeight(long height) this.height = height ; public long getWidth() return this.width ; public long getHe
10、ight() return this.height ; public class Square implements Quadrangle private long side ; public void setSide(long side) this.side = side ; public long getSide() return this.side ; public long getWidth() return getSide() ; public long getHeight() return getSide() ; public class Test public static vo
11、id main(String args) public void resizeQuadrangle r) while(r.getWidth <= r.getHeight) r.setWidth(r.getWidth() + 1) ; 合成/聚合复用原则(CARP):又称合成复用原则(CRP),就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。简而言之就是:要尽量使用合成/聚合,尽量不要使用继承。依赖倒转原则依赖倒转原则的一种表述是:细节应当依赖与抽象,抽象不应当依赖于细节。 另一种描述是:要针对接口编程,不要针对实现编程
12、。意思就是应当使用接口和抽象类而不是具体类进行变量的类型声明、参数的类型声明、方法的返回类型声明以 及数据类型的转换等。要保证这一点,一个具体java类应当只实现java接口和抽象java类中声明过的方法,而不应当给出多余的方法。 1 /Dependency Inversion Principle - Good example2 interface IWorker 3 publicvoid work(); 4 5 class Worker implements IWorker 6 publicvoid work() 7 / .working8 9 10 class SuperWorker im
13、plements IWorker 11 publicvoid work() 12 /. working much more13 14 15 class Manager 16 IWorker m_worker; 17 publicvoid setWorker(IWorker w) 18 m_worker=w; 19 20 publicvoid manage() 21 m_worker.work(); 22 23 接口隔离下面是实现的代码./-这儿不用接口继承,因为可能出现修改了父接口影响了子接口interface IOrderForPortal String getOrder();interfa
14、ce IOrderForOtherSys String insertOrder(); String getOrder();interface IOrderForAdmin /extends IOrderForPortal,IOrderForOtherSys String deleteOrder(); String updateOrder(); String insertOrder(); String getOrder();/*interface IOrderForPortal String getOrder();interface IOrderForOtherSys String insert
15、Order();interface IOrderForAdmin extends IOrderForPortal,IOrderForOtherSys String updateOrder(); String deleteOrder();*/class Order implements IOrderForPortal,IOrderForOtherSys,IOrderForAdmin private Order() /-什么都不干,就是为了不让直接 new,防止客户端直接New,然后访问它不需要的方法. /返回给Portal public static IOrderForPortal getOrd
16、erForPortal() return (IOrderForPortal)new Order(); /返回给OtherSys public static IOrderForOtherSys getOrderForOtherSys() return (IOrderForOtherSys)new Order(); /返回给Admin public static IOrderForAdmin getOrderForAdmin() return (IOrderForAdmin)new Order(); /-下面是接口方法的实现.只是返回了一个String用于演示- public String get
17、Order() return "implemented getOrder" public String insertOrder() return "implemented insertOrder" public String updateOrder() return "implemented updateOrder" public String deleteOrder() return "implemented deleteOrder" public class TestCreateLimit public sta
18、tic void main(String args) IOrderForPortal orderForPortal = Order.getOrderForPortal(); IOrderForOtherSys orderForOtherSys = Order.getOrderForOtherSys(); IOrderForAdmin orderForAdmin = Order.getOrderForAdmin(); System.out.println("Portal门户调用方法:"+orderForPortal.getOrder(); System.out.println
19、("OtherSys外部系统调用方法:"+orderForOtherSys.insertOrder(); System.out.println("Admin管理后台调用方 法:"+orderForAdmin.getOrder()+""+orderForAdmin.insertOrder()+""+orderForAdmin.updateOrder()+""+orderForAdmin.deleteOrder(); 迪米特法则一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的
20、单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。public class SomeOne public void operator1(Friend friend) Stranger stranger=vide(); stranger.operation3(); public class Friend private Stranger stranger=new Stranger(); public void ope
21、ration2() public Stranger provide() return stranger; 显然,SomeOne的方法operation1()不满足迪米特法则,因为这个方法引用了Stranger对象,而Stranger对象不是SomeOne的朋友。public class SomeOne public void operation1(Friend friend) friend.forward(); SomeOne通过调用自己朋友Friend对象的forward()方法作到了原来需要调用Stranger对象才能做到的事情。public class Friend private St
22、ranger stranger=new Stranger(); public void operation2() public void forward() stranger.operation3(); 在系统的某一个类需要修改时,仅仅会直接影响到这个类的“朋友们”,而不会直接影响到其他部分。Factory Method定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。适用性 当一个类不知道它所必须创建的对象的类的时候。当一个类希望由它的子类来指定它所创建的对象的时候。当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将
23、哪一个帮助子类是代理者这一信息局部化的时候。按照图1中所定义的结构写了下面的一段演示代码.这段代码的作用是创建不同的Shape实例,每个实例完成两个操作:draw和erase.具体的创建过程委托?oShapeFactory来完成.1.a 首先定义一个抽象类Shape,定义两个抽象的方法.1abstractclassShape 23/勾画shape45publicabstractvoiddraw();67/擦去 shape89publicabstractvoiderase();1011publicString name;1213publicShape(String aName)1415name=
24、aName;1617181920211.b 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法1/圆形子类23classCircleextendsShape 45publicvoiddraw() 67System.out.println("It will draw a circle.");891011publicvoiderase() 1213System.out.println("It will erase a circle.");14151617/构造函数1819publicCircle(String aNam
25、e)2021super(aName);222324252627/方形子类2829classSquareextendsShape 3031publicvoiddraw() 3233System.out.println("It will draw a square.");34353637publicvoiderase() 3839System.out.println("It will erase a square.");40414243/构造函数4445publicSquare(String aName)4647super(aName);4849505152
26、531.c 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作.1abstractclassShapeFactory 23protectedabstractShape factoryMethod(String aName);45/在anOperation中定义Shape的一系列行为67publicvoidanOperation(String aName)89Shape s=factoryMethod(aName);1011System.out.println("The current shape is:"+s.nam
27、e);1213s.draw();1415s.erase();1617181920211.d 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法1/定义返回 circle 实例的 CircleFactory23classCircleFactoryextendsShapeFactory 45/重载factoryMethod方法,返回Circle对象67protectedShape factoryMethod(String aName) 89returnnewCircle(aName+"(c
28、reated by CircleFactory)");101112131415/定义返回 Square 实例的 SquareFactory1617classSquareFactoryextendsShapeFactory 1819/重载factoryMethod方法,返回Square对象2021protectedShape factoryMethod(String aName) 2223returnnewSquare(aName+"(created by SquareFactory)");242526272829 1.e 测试类:请注意这个客户端程序多么简洁,既没
29、有罗嗦的条件判断语句,也无需关心ConcreteProduct和ConcreteCreator的细节 (因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放 到客户程序中也是不错的).1classMain 23publicstaticvoidmain(String args)45ShapeFactory sf1=newSquareFactory();67ShapeFactory sf2=newCircleFactory();89sf1.anOperation("Shape one");
30、1011sf2.anOperation("Shape two");121314151617运行结果如下:1The current shape is: Shape one (created by SquareFactory)23It will draw a square.45It will erase a square.67The current shape is: Shape two (created by CircleFactory)89It will draw a circle.1011It will erase a circle.1213 参数化的Factory Me
31、thod: 这种方式依靠指定的参数作为标志来创建对应的实例,这是很常见的一种办法.比如JFC中的BorderFactory就是个很不错的例子. 以下的这个例子是用字符串作为标记来进行判断的,如果参数的类型也不一样,那就可以用到过载函数来解决这个问题,定义一系列参数和方法体不同的同名函数, 这里java.util.Calendar.getInstance()又是个极好的例子.参数化的创建方式克服了Factory Method模式一个最显著的缺陷,就是当具体产品比较多时,我们不得不也建立一系列与之对应的具体构造器. 但是在客户端我们必须指定参数来决定要创建哪一个类.2.a 我们在第一种方法的基础上
32、进行修改,首先自定义一个的异常,这样当传入不正确的参数时可以得到更明显的报错信息.1classNoThisShapeextendsException 23publicNoThisShape(String aName) 45super(aName);678910112.b去掉了ShapeFactory的两个子类,改为由ShapeFactory直接负责实例的创建. ShapeFactory自己变成一个具体的创建器,直接用参数化的方法实现factoryMethod返回多种对象.1abstractclassShapeFactory 23privatestaticShape s;45privateSha
33、peFactory() 67staticShape factoryMethod(String aName, String aType)throwsNoThisShape89if(aTpareTo("square")=0)1011returnnewSquare(aName);1213elseif(aTpareTo("circle")=0)1415returnnewCircle(aName);1617elsethrownewNoThisShape(aType);18192021/在anOperation中定义Shape的一系列行为2223staticvoid
34、anOperation(String aName, String aType)throwsNoThisShape2425s=factoryMethod(aName, aType);2627System.out.println("The current shape is:"+);2829s.draw();3031s.erase();3233343536372.c 测试类:这里客户端必须指定参数来决定具体创建哪个类.这个例子里的anOperation是静态函数,可以直接引用.1classMain 23publicstaticvoidmain(String args)
35、throwsNoThisShape45ShapeFactory.anOperation("Shape one","circle");67ShapeFactory.anOperation("Shape two","square");89ShapeFactory.anOperation("Shape three","delta");101112131415运行结果如下:1classMain 23publicstaticvoidmain(String args)throwsNoTh
36、isShape45ShapeFactory.anOperation("Shape one","circle");67ShapeFactory.anOperation("Shape two","square");89ShapeFactory.anOperation("Shape three","delta");101112131415Abstract Factory提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 适用性 一个系统要独立于它的产品的创建、组合
37、和表示时。 一个系统要由多个产品系列中的一个来配置时。 当你要强调一系列相关的产品对象的设计以便进行联合使用时。 当你提供一个产品类库,而只想显示它们的接口而不是实现时。图中,我们可以看到,客户需要得到某系列的产品的时候,直接用相应的工厂子类来创建产品就可以了。比如,当需要生产Fit时,就用FitFactory,等到换班之后,要生产Odyssey了,直接使用OdysseyFactory替换FitFactory就行了,至于怎么替换就随便了,GoF也给了我们一些建议,我将在后面总结创建型模式的时候讲。把上面的类图转换成代码,应该是这个样子。 关于车门的类:publicabstractclass A
38、bstractDoor publicclass FitDoor : AbstractDoor publicclass OdysseyDoor : AbstractDoor 关于底盘的类:publicabstractclass AbstractChassis publicclass FitChassis : AbstractChassis publicclass OdysseyChassis : AbstractChassis 关于工厂的类:publicabstractclass HondaFactory publicabstract AbstractDoor CreateDoor();publ
39、icabstract AbstractChassis CreateChassis(); publicclass FitFactory public AbstractDoor CreateDoor() returnnew FitDoor(); public AbstractChassis CreateChassis() returnnew FitChassis(); publicclass OdysseyFactory public AbstractDoor CreateDoor() returnnew OdysseyDoor(); public AbstractChassis CreateCh
40、assis() returnnew OdysseyChassis(); 客户的调用:publicclass Client private AbstractDoor _door;private AbstractChassis _chassis;private HondaFactory _factory;publicvoid GetACar(string seriesName) this.PrepareFactory(seriesName);this._door = this._factory.CreateDoor();this._chassis = this._factory.CreateCha
41、ssis();/ TODO: Make a car! privatevoid PrepareFactory(string seriesName) switch(seriesName) case "Fit":this._factory = new FitFactory();break;case "Odyssey":this._factory = new OdysseyFactory();break; Builder将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。适用性 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方
42、式时。 当构造过程必须允许被构造的对象有不同的表示时。拿广本来打比方。广本的四个车间,最开头的是冲压科,而在冲压科的门口有一间小房子,里面放了一台激光焊接机,它用它的机械手臂抓起旁边放着的各种各样 的钢板,不停的焊接。可能有人要问,这是什么例子?这就是生成器!一般来说,汽车各处外壳的厚度以及硬度是不同的,比如车头部分就要够硬(用来撞的_), 其他一些地方比如车顶就没有必要用超厚的钢板。这样,一来可以降低整车的质量,可以省油;二来可以降低成本(所以广本暴利啊其实其他汽车厂家也这么 干)先前所讲的焊接机就是干这个事情的,它将各种不同厚度不同硬度的钢板焊接在一起,供那些巨型的冲压机来冲压成型,以生产
43、汽车的各个不同的部分。各种汽 车所使用的合成钢板的组成是不一样的,但冲压机不管那么多,它只管压钢板。这样一来就明白了吧?焊接机将各种钢板按照规定焊接成不同组成的合成钢板,至于 它是如何焊接的以及合成钢板的组成,冲压机对这些信息是不关心的。我们来看一个类图。publicclass Steel publicobject Part00;publicobject Part01;publicobject Part10;publicobject Part11; publicclass WeldingProgramme object _materials;public WeldingProgramme()
44、this._materials = newobject4;/ TODO: Add some materials public Steel Go() SteelWelder sw = new SteelWelder();foreach(object m inthis._materials) sw.WeldSteel(m); / you can weld the steel like this / sw.WeldSteel(this._materials3); / sw.WeldSteel(this._materials2); / sw.WeldSteel(this._materials1); /
45、 sw.WeldSteel(this._materials0); / also, you can do it like this / sw.WeldSteel(this._materials2); / sw.WeldSteel(this._materials1); / sw.WeldSteel(this._materials0); / sw.WeldSteel(this._materials3);return sw.GetSteel(); publicclass SteelWelder Steel _steel;publicvoid WeldSteel(object materials) if
46、(this._steel = null)this._steel = new Steel();if(this._steel.Part00 = null) this._steel.Part00 = materials; elseif(this._steel.Part01 = null) this._steel.Part01 = materials; elseif(this._steel.Part10 = null) this._steel.Part10 = materials; elseif(this._steel.Part11 = null) this._steel.Part11 = mater
47、ials; else thrownew Exception("what do you want?"); public Steel GetSteel() returnthis._steel; publicclass Punch private Steel _steel;publicvoid Work() WeldingProgramme wp = new WeldingProgramme();this._steel = wp.Go();/ TODO: Punch the Steel Prototype用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 适用性 当
48、要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。生物细胞的自身复制;根据产品模型生产产品等等Prototype模式的模型定义: Prototype +clone():Prototype 即:原型类Prototype 提供clone()方法,实现对对象自身的复制(克隆)。 UML类图: Prototype模式的实现范例下面我们使用Prototype模式来实现细胞(Cell)的自身复制过程。 Java语言提供了对象复制的
49、机制,Prototype模式的Java实现一般也通过实现Cloneable接口来实现。 这里我们也通过实现Cloneable接口来说明Prototype模式。1 public class Cell implements Cloneable 2 /细胞壁 3 private String cellWall; 4 /细胞膜 5 private String cellMembrane; 6 /细胞组织 7 private String cellularTissue; 8 ./这里省略掉了对成员变量的setter/getter方法的定义 9 /细胞的自身复制 10 /这里重载了Obect#clone(
50、)方法,为了方便外部调用,把返回值由Object修改为Cell,并把访问级别设置为public 11 public Cell clone() 12 try 13 /只需简单地调用super.clone();即可 14 return (Cell) super .clone(); 15 catch (CloneNotSupportedException e) 16 throw ( new InternalError(e.getMessage(); 17 18 19 20 /调用方: 21 public class Client 22 public static void main(String a
51、rgs) 23 /准备原型细胞 24 Cell cell = new Cell(); 25 cell.setCellWall("cell wall 1" ); 26 . 27 /克隆原型细胞 28 Cell clonedCell = cell.clone(); 29 . 30 /操作被克隆的细胞(略) 31 32 Singleton保证一个类仅有一个实例,并提供一个访问它的全局访问点。 适用性 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。public class S
52、ingleton private static Singleton instance = null; public static synchronized Singleton getInstance() if (instance=null) instancenew Singleton(); return instance; Adapter将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 适用性 你想使用一个已经存在的类,而它的接口不符合你的需求。 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。 (仅适用于对象A d a p t e r )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。我们就使用设计模式精解里面的场景,现在有一个图形类,此类的行为有: 设定一个Shape对象的位置 获取一个Shape对象的位置 显示一个Shape对象(display) 填充一个Shape对象(fill) 设置一个Shape对象的颜色 擦除一个S
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024商业购物中心二次元潮玩店谷子店周年庆活动策划案
- 循环系统疾病患者的护理
- 小学二年级数学上册加减乘除混合口算题
- 企业股权收购合同范例
- 买卖儿童农村房屋合同范例
- 劳务输送框架合同范本
- 企业集资合同范例
- 临时兼职用工合同范例
- 加盟拿料合同范例
- 入园合同范例
- 戴德梁行物业培训ppt课件
- 回转式空气预热器安装作业指导书
- GB∕T 16422.3-2022 塑料 实验室光源暴露试验方法 第3部分:荧光紫外灯
- 第三章1轨道电路
- 煤矿防治水中长期规划2017—2019
- 2022年乡镇(街道)执法人员资格考试题库(含答案)
- 新版广西大学毕业设计封面
- 汽机各系统吹管调试方案
- 金华市区低丘缓坡综合开发利用研究
- MATLAB在电力系统中应用
- 基于深度学习的图像压缩感知算法综述
评论
0/150
提交评论