




已阅读5页,还剩48页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
开闭原则开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。 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); public 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(Pear 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(); public 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 getGardener() 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(); Fruit tempPear; gardenerBase pearGarden = PearGardener.getGardener(); tempPear = pearGarden.getFruit(); 里氏代换原则一个软件实体如果使用的是一个基类的话,那么一定适用于其子类。而且它觉察不出基类对象和子类对象的区别。也就是说,在软件里面,把基类都替换成它的子类,程序的行为没有变化。反过来的代换不成立,如果一个软件实体使用的是一个子类的话,那么它不一定适用于基类。里氏代换原则的四层含义1)子类必须完全实现父类的方法。在类中调用其他类是务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则。2)子类可以有自己的个性。子类当然可以有自己的行为和外观了,也就是方法和属性3)覆盖或实现父类的方法时输入参数可以被放大。即子类可以重载父类的方法,但输入参数应比父类方法中的大,这样在子类代替父类的时候,调用的仍然是父类的方法。即以子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松。4)覆盖或实现父类的方法时输出结果可以被缩小。4、里氏代换原则在设计模式中的体现 策略模式(Strategy) 如果有一组算法,那么就将算法封装起来,使得它们可以互换。客户端依赖于基类类型,而变量的真实类型则是具体策略类。这是具体策略焦色可以“即插即用”的关键。 合成模式(Composite) 合成模式通过使用树结构描述整体与部分的关系,从而可以将单纯元素与符合元素同等看待。由于单纯元素和符合元素都是抽象元素角色的子类,因此两者都可以替代抽象元素出现在任何地方。里氏代换原则是合成模式能够成立的基础。 代理模式(Proxy) 代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。代理模式能够成立的关键,就在于代理模式与真实主题模式都是抽象主题角色的子类。客户端只知道抽象主题,而代理主题可以替代抽象主题出现在任何需要的地方,而将真实主题隐藏在幕后。里氏代换原则是代理模式能够成立的基础。public interface Quadrangle public long 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 getHeight() 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 void main(String args) public void resizeQuadrangle r) while(r.getWidth = r.getHeight) r.setWidth(r.getWidth() + 1) ; 合成/聚合复用原则(CARP):又称合成复用原则(CRP),就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。简而言之就是:要尽量使用合成/聚合,尽量不要使用继承。依赖倒转原则依赖倒转原则的一种表述是:细节应当依赖与抽象,抽象不应当依赖于细节。 另一种描述是:要针对接口编程,不要针对实现编程。意思就是应当使用接口和抽象类而不是具体类进行变量的类型声明、参数的类型声明、方法的返回类型声明以 及数据类型的转换等。要保证这一点,一个具体java类应当只实现java接口和抽象java类中声明过的方法,而不应当给出多余的方法。 1 /Dependency Inversion Principle - Good example 2 interface IWorker 3 public void work(); 4 5 6 class Worker implements IWorker 7 public void work() 8 / .working 9 10 11 12 class SuperWorker implements IWorker 13 public void work() 14 /. working much more 15 16 17 18 class Manager 19 IWorker m_worker; 20 21 public void setWorker(IWorker w) 22 m_worker=w; 23 24 public void manage() 25 m_worker.work(); 26 27 接口隔离下面是实现的代码./-这儿不用接口继承,因为可能出现修改了父接口影响了子接口interface IOrderForPortal String getOrder();interface 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 insertOrder();interface IOrderForAdmin extends IOrderForPortal,IOrderForOtherSys String updateOrder(); String deleteOrder();*/class Order implements IOrderForPortal,IOrderForOtherSys,IOrderForAdmin private Order() /-什么都不干,就是为了不让直接 new,防止客户端直接New,然后访问它不需要的方法. /返回给Portal public static IOrderForPortal getOrderForPortal() 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 getOrder() 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 static 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(OtherSys外部系统调用方法:+orderForOtherSys.insertOrder(); System.out.println(Admin管理后台调用方 法:+orderForAdmin.getOrder()+;+orderForAdmin.insertOrder()+;+orderForAdmin.updateOrder()+;+orderForAdmin.deleteOrder(); 迪米特法则一个软件实体应当尽可能少的与其他实体发生相互作用。每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。public class SomeOne public void operator1(Friend friend) Stranger stranger=vide(); stranger.operation3(); public class Friend private Stranger stranger=new Stranger(); public void operation2() 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 Stranger stranger=new Stranger(); public void operation2() public void forward() stranger.operation3(); 在系统的某一个类需要修改时,仅仅会直接影响到这个类的“朋友们”,而不会直接影响到其他部分。Factory Method定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。适用性 当一个类不知道它所必须创建的对象的类的时候。当一个类希望由它的子类来指定它所创建的对象的时候。当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。按照图1中所定义的结构写了下面的一段演示代码.这段代码的作用是创建不同的Shape实例,每个实例完成两个操作:draw和erase.具体的创建过程委托?oShapeFactory来完成.1.a 首先定义一个抽象类Shape,定义两个抽象的方法.1abstract class Shape 23/ 勾画shape45public abstract void draw();67/ 擦去 shape89public abstract void erase();1011public String name;1213public Shape(String aName)1415name= aName;1617181920211.b 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法1/ 圆形子类23class Circleextends Shape 45public void draw() 67System.out.println(It will draw a circle.);891011public void erase() 1213System.out.println(It will erase a circle.);14151617/ 构造函数1819public Circle(String aName)2021super(aName);222324252627/ 方形子类2829class Squareextends Shape 3031public void draw() 3233System.out.println(It will draw a square.);34353637public void erase() 3839System.out.println(It will erase a square.);40414243/ 构造函数4445public Square(String aName)4647super(aName);4849505152531.c 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作.1abstract class ShapeFactory 23protected abstract Shape factoryMethod(String aName);45/ 在anOperation中定义Shape的一系列行为67public void anOperation(String aName)89Shape s= factoryMethod(aName);1011System.out.println(The current shape is: + );1213s.draw();1415s.erase();1617181920211.d 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法1/ 定义返回 circle 实例的 CircleFactory23class CircleFactoryextends ShapeFactory 45/ 重载factoryMethod方法,返回Circle对象67protected Shape factoryMethod(String aName) 89return new Circle(aName+ (created by CircleFactory);101112131415/ 定义返回 Square 实例的 SquareFactory1617class SquareFactoryextends ShapeFactory 1819/ 重载factoryMethod方法,返回Square对象2021protected Shape factoryMethod(String aName) 2223return new Square(aName+ (created by SquareFactory);242526272829 1.e 测试类:请注意这个客户端程序多么简洁,既没有罗嗦的条件判断语句,也无需关心ConcreteProduct和ConcreteCreator的细节 (因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放 到客户程序中也是不错的).1class Main 23public static void main(String args)45ShapeFactory sf1= new SquareFactory();67ShapeFactory sf2= new CircleFactory();89sf1.anOperation(Shape one);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 Method: 这种方式依靠指定的参数作为标志来创建对应的实例,这是很常见的一种办法.比如JFC中的BorderFactory就是个很不错的例子. 以下的这个例子是用字符串作为标记来进行判断的,如果参数的类型也不一样,那就可以用到过载函数来解决这个问题,定义一系列参数和方法体不同的同名函数, 这里java.util.Calendar.getInstance()又是个极好的例子.参数化的创建方式克服了Factory Method模式一个最显著的缺陷,就是当具体产品比较多时,我们不得不也建立一系列与之对应的具体构造器. 但是在客户端我们必须指定参数来决定要创建哪一个类.2.a 我们在第一种方法的基础上进行修改,首先自定义一个的异常,这样当传入不正确的参数时可以得到更明显的报错信息.1class NoThisShapeextends Exception 23public NoThisShape(String aName) 45super(aName);678910112.b去掉了ShapeFactory的两个子类,改为由ShapeFactory直接负责实例的创建. ShapeFactory自己变成一个具体的创建器,直接用参数化的方法实现factoryMethod返回多种对象.1abstract class ShapeFactory 23private static Shape s;45private ShapeFactory() 67static Shape factoryMethod(String aName, String aType)throws NoThisShape89if (aTpareTo(square)=0)1011return new Square(aName);1213else if (aTpareTo(circle)=0)1415return new Circle(aName);1617else throw new NoThisShape(aType);18192021/ 在anOperation中定义Shape的一系列行为2223static void anOperation(String aName, String aType)throws NoThisShape2425s= factoryMethod(aName, aType);2627System.out.println(The current shape is: + );2829s.draw();3031s.erase();3233343536372.c 测试类:这里客户端必须指定参数来决定具体创建哪个类.这个例子里的anOperation是静态函数,可以直接引用.1class Main 23public static void main(String args)throws NoThisShape45ShapeFactory.anOperation(Shape one,circle);67ShapeFactory.anOperation(Shape two,square);89ShapeFactory.anOperation(Shape three,delta);101112131415运行结果如下:1class Main 23public static void main(String args)throws NoThisShape45ShapeFactory.anOperation(Shape one,circle);67ShapeFactory.anOperation(Shape two,square);89ShapeFactory.anOperation(Shape three,delta);101112131415Abstract Factory提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 适用性 一个系统要独立于它的产品的创建、组合和表示时。 一个系统要由多个产品系列中的一个来配置时。 当你要强调一系列相关的产品对象的设计以便进行联合使用时。 当你提供一个产品类库,而只想显示它们的接口而不是实现时。图中,我们可以看到,客户需要得到某系列的产品的时候,直接用相应的工厂子类来创建产品就可以了。比如,当需要生产Fit时,就用FitFactory,等到换班之后,要生产Odyssey了,直接使用OdysseyFactory替换FitFactory就行了,至于怎么替换就随便了,GoF也给了我们一些建议,我将在后面总结创建型模式的时候讲。把上面的类图转换成代码,应该是这个样子。 关于车门的类: public abstract class AbstractDoor public class FitDoor : AbstractDoor public class OdysseyDoor : AbstractDoor 关于底盘的类: public abstract class AbstractChassis public class FitChassis : AbstractChassis public class OdysseyChassis : AbstractChassis 关于工厂的类: public abstract class HondaFactory public abstract AbstractDoor CreateDoor(); public abstract AbstractChassis CreateChassis(); public class FitFactory public AbstractDoor CreateDoor() return new FitDoor(); public AbstractChassis CreateChassis() return new FitChassis(); public class OdysseyFactory public AbstractDoor CreateDoor() return new OdysseyDoor(); public AbstractChassis CreateChassis() return new OdysseyChassis(); 客户的调用: public class Client private AbstractDoor _door; private AbstractChassis _chassis; private HondaFactory _factory; public void GetACar(string seriesName) this.PrepareFactory(seriesName); this._door = this._factory.CreateDoor(); this._chassis = this._factory.CreateChassis(); / TODO: Make a car! private void PrepareFactory(string seriesName) switch(seriesName) case Fit: this._factory = new FitFactory(); break; case Odyssey: this._factory = new OdysseyFactory(); break; Builder将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。适用性 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 当构造过程必须允许被构造的对象有不同的表示时。拿广本来打比方。广本的四个车间,最开头的是冲压科,而在冲压科的门口有一间小房子,里面放了一台激光焊接机,它用它的机械手臂抓起旁边放着的各种各样 的钢板,不停的焊接。可能有人要问,这是什么例子?这就是生成器!一般来说,汽车各处外壳的厚度以及硬度是不同的,比如车头部分就要够硬(用来撞的_), 其他一些地方比如车顶就没有必要用超厚的钢板。这样,一来可以降低整车的质量,可以省油;二来可以降低成本(所以广本暴利啊其实其他汽车厂家也这么 干)先前所讲的焊接机就是干这个事情的,它将各种不同厚度不同硬度的钢板焊接在一起,供那些巨型的冲压机来冲压成型,以生产汽车的各个不同的部分。各种汽 车所使用的合成钢板的组成是不一样的,但冲压机不管那么多,它只管压钢板。这样一来就明白了吧?焊接机将各种钢板按照规定焊接成不同组成的合成钢板,至于 它是如何焊接的以及合成钢板的组成,冲压机对这些信息是不关心的。我们来看一个类图。 public class Steel public object Part00; public object Part01; public object Part10; public object Part11; public class WeldingProgramme object _materials; public WeldingProgramme() this._materials = new object4; / TODO: Add some materials public Steel Go() SteelWelder sw = new SteelWelder(); foreach(object m in this._materials) sw.WeldSteel(m); / you can weld the steel like this / sw.WeldSteel(this._materials3); / sw.WeldSteel(this._materials2); / sw.WeldSteel(this._materials1); / 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(); public class SteelWelder Steel _steel; public void WeldSteel(object materials) if(this._steel = null) this._steel = new Steel(); if(this._steel.Part00 = null) this._steel.Part00 = materials; else if(this._steel.Part01 = null) this._steel.Part01 = materials; else if(this._steel.Part10 = null) this._steel.Part10 = materials; else if(this._steel.Part11 = null) this._steel.Part11 = materials; else throw new Exception(what do you want?); public Steel GetSteel() return this._steel; public class Punch private Steel _steel; public void Work() WeldingProgramme wp = new WeldingProgramme(); this._steel = wp.Go(); / TODO: Punch the Steel Prototype用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 浙江国企招聘2025台州温岭市粮食收储有限责任公司招聘14人笔试参考题库附带答案详解
- 五险一金/年薪12万五九煤炭(集团)招聘50人笔试参考题库附带答案详解
- 2025内蒙古包头市中运铁路运输设备有限公司招聘238人笔试参考题库附带答案详解
- 中国医科大学《审计案例与模拟》2023-2024学年第二学期期末试卷
- 黔南民族职业技术学院《中小学信息技术教学法》2023-2024学年第二学期期末试卷
- 雅安职业技术学院《戏剧影视表演片段训练》2023-2024学年第二学期期末试卷
- 河北科技学院《中医儿科学理论》2023-2024学年第二学期期末试卷
- 陕西科技大学镐京学院《通信系统DSP》2023-2024学年第二学期期末试卷
- 洛阳师范学院《安全科学进展》2023-2024学年第二学期期末试卷
- 徐州工业职业技术学院《教学能力训练》2023-2024学年第二学期期末试卷
- 中信证券公司融资融券业务方案设计
- SZDBZ 194-2016 公园设施维护技术规范
- DBJ04T 289-2020 建筑工程施工安全资料管理标准
- 化工设计知到智慧树章节测试课后答案2024年秋浙江大学
- 《建筑构造与识图》课程标准
- 2025年保健食品从业人员培训考试试题
- 2025年贵州盘江精煤股份有限公司招聘笔试参考题库含答案解析
- 2024年中考数学复习:中点模型专项练习
- 旅行社企业章程范本
- 2025年宁波余姚市直属企业招招聘笔试参考题库含答案解析
- 《心理健康测试》课件
评论
0/150
提交评论