河南某某视频监控有限公司欢迎您!

通俗易懂-举例解释设计模式-原则篇

本文摘要:设计模式开始之前,你一定需要知道的七大原则,划分是一下七种:单一职责原则接口隔离原则依赖倒置原则里氏替换原则开闭原则迪米特原则合成复用原则前面已经先容了1和2,今天来先容3和4。依赖倒置原则先做个先容,看不懂没关系,看懂更好。高层模块不应该依赖低层模块,二者都应该依赖其抽象抽象(接口)不应该依赖细节(实现类),细节应该依赖抽象依赖倒转(倒置)的中心思想是面向接口编程。 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的工具要稳定的多。

亚博电子游戏平台

设计模式开始之前,你一定需要知道的七大原则,划分是一下七种:单一职责原则接口隔离原则依赖倒置原则里氏替换原则开闭原则迪米特原则合成复用原则前面已经先容了1和2,今天来先容3和4。依赖倒置原则先做个先容,看不懂没关系,看懂更好。高层模块不应该依赖低层模块,二者都应该依赖其抽象抽象(接口)不应该依赖细节(实现类),细节应该依赖抽象依赖倒转(倒置)的中心思想是面向接口编程。

依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的工具要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。

在java中,抽象指的是接口或抽象类,细节就是详细的实现类。使用接口或抽象类的目的是制定好规范,而不涉及任何详细的操作,把展现细节的任务交给他们的实现类去完成也许你看的也不是太明确,没关系,用代码来解释一下。//完成Person吸收消息的功效//方式1分析//简朴,比力容易想到class Email {public String getInfo() {return "电子邮件信息: hello,world";}}class Person {public void receive(Email email ) {System.out.println(email.getInfo());}}public class DependecyInversion {public static void main(String[] args) {Person person = new Person();person.receive(new Email());}}# 可是如果我们获取的工具是微信,短信等等,则新增类,同时Perons也要增加相应的吸收方法class Email {public String getInfo() {return "电子邮件信息: hello,world";}}# 新增部门class WeChat {public String getInfo() {return "WeChat信息: hello,world";}}class Person {public void receive(Email email ) {System.out.println(email.getInfo());}# 新增部门 通过这可以发现,如果我们再新增短信,就会不听的在这里添加吸收方法public void receive(Wechat wechat) {System.out.println(wechat.getInfo());}}public class DependecyInversion {public static void main(String[] args) {Person person = new Person();person.receive(new Email());# 新增部门person.receive(new WeChat());}}上面方式的毛病显而易见。

接下来做个革新。解决思路: 引入一个抽象的接口IReceiver,表现吸收者,这样Person类与接口IReceiver 发生依赖,因为Email, WeiXin等等属于吸收的规模,他们各自实现IReceiver 接口就ok,这样我们就符号依赖倒转原则。代码实现://界说接口interface IReceiver {public String getInfo();}class Email implements IReceiver {public String getInfo() {return "电子邮件信息: hello,world";}}//增加微信class WeiXin implements IReceiver {public String getInfo() {return "微信信息: hello,ok";}}//方式2class Person {//这里我们是对接口的依赖public void receive(IReceiver receiver ) {System.out.println(receiver.getInfo());}}public class DependecyInversion {public static void main(String[] args) {//客户端无需改变Person person = new Person();person.receive(new Email());person.receive(new WeiXin());}}# 通过这种方式可以发现,我们的Person类中,不会再因为新增一个类,就要去增加一个方法下面先容依赖关系通报的的三种式和应用案例(相识即可)接口通报# 方式1: 通过接口通报实现依赖# 开关的接口interface IOpenAndClose { public void open(ITV tv); //抽象方法,吸收接口}interface ITV { //ITV接口 public void play();}class ChangHong implements ITV {@Overridepublic void play() {// TODO Auto-generated method stubSystem.out.println("长虹电视机,打开");} }// 实现接口class OpenAndClose implements IOpenAndClose{ public void open(ITV tv){ tv.play(); }}public class DependencyPass {public static void main(String[] args) {ChangHong changHong = new ChangHong();OpenAndClose openAndClose = new OpenAndClose();openAndClose.open(changHong); }}结构方法通报# 方式2: 通过结构方法依赖通报interface IOpenAndClose { public void open(); //抽象方法}interface ITV { //ITV接口 public void play();}class OpenAndClose implements IOpenAndClose{ public ITV tv; //成员 public OpenAndClose(ITV tv){ //结构器 this.tv = tv; } public void open(){ this.tv.play(); } }public class DependencyPass {public static void main(String[] args) { //通过结构器举行依赖通报OpenAndClose openAndClose = new OpenAndClose(changHong); openAndClose.open();}}setter方式通报// 方式3 , 通过setter方法通报interface IOpenAndClose {public void open(); // 抽象方法public void setTv(ITV tv);}interface ITV { // ITV接口public void play();}class OpenAndClose implements IOpenAndClose {private ITV tv;public void setTv(ITV tv) {this.tv = tv;}public void open() {this.tv.play();}}class ChangHong implements ITV {@Overridepublic void play() {// TODO Auto-generated method stubSystem.out.println("长虹电视机,打开");} }public class DependencyPass {public static void main(String[] args) { //通过setter方法举行依赖通报OpenAndClose openAndClose = new OpenAndClose();openAndClose.setTv(changHong);openAndClose.open();}}依赖倒置原则注意事项:低层模块只管都要有抽象类或接口,或者两者都有,法式稳定性更好.变量的声明类型只管是抽象类或接口,这样我们的变量引用和实际工具间,就存在一个缓冲层,利于法式扩展和优化继续时遵循里氏替换原则里氏替换原则为什么会有里氏(人名)原则?继续包罗这样一层寄义:父类中通常已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些契约,可是如果子类对这些已经实现的方法任意修改,就会对整个继续体系造成破坏。

继续在给法式设计带来便利的同时,也带来了毛病。好比使用继续会给法式带来侵入性,法式的可移植性降低,增加工具间的耦合性,如果一个类被其他的类所继续,则当这个类需要修改时,必须思量到所有的子类,而且父类修改后,所有涉及到子类的功效都有可能发生故障。问题提出:在编程中,如何正确的使用继续? 由此提出里氏替换原则基本先容里氏替换原则(Liskov Substitution Principle)在1988年,由麻省理工学院的以为姓里的女士提出的。

如果对每个类型为T1的工具o1,都有类型为T2的工具o2,使得以T1界说的所有法式Р在所有的工具o1都代换成o2时,法式Р的行为没有发生变化,那么类型T2是类型T1的子类型。换句话说,所有引用基类的地方必须能透明地使用其子类的工具。

在使用继续时,遵循里氏替换原则,在子类中只管不要重写父类的方法。里氏替换原则告诉我们,继续实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖来解决问题。

亚博电子游戏平台

关于聚合,组合,依赖也是很重要的一部门,详细请参考我上一篇文章。下面通过代码来让你对里氏原则有一个更好的明白。// A类class A {// 返回两个数的差public int func1(int num1, int num2) {return num1 - num2;}}// B类继续了A// 增加了一个新功效:完成两个数相加,然后和9求和class B extends A {//这里,重写了A类的方法, 可能是无意识public int func1(int a, int b) {return a + b;}public int func2(int a, int b) {return func1(a, b) + 9;}}public class Liskov {public static void main(String[] args) {// TODO Auto-generated method stubA a = new A();System.out.println("11-3=" + a.func1(11, 3));System.out.println("1-8=" + a.func1(1, 8));System.out.println("-----------------------");B b = new B();System.out.println("11-3=" + b.func1(11, 3));//这里本意是求出11-3System.out.println("1-8=" + b.func1(1, 8));// 1-8System.out.println("11+3+9=" + b.func2(11, 3));}}# 我们发现原来运行正常的相减功效发生了错误。

原因就是类B无意中重写了父类的方法,造成原有# 功效泛起错误。在实际编程中,我们经常会通过重写父类的方法完成新的功效,这样写起来虽然简 单,但整个继续体系的复用性会比力差。

特别是运行多态比力频繁的时候。通用的做法是:原来的父类和子类都继续一个更通俗的基类,原有的继续关系去掉,接纳依赖,聚合,组合等关系取代。革新代码实现//建立一个越发基础的基类class Base {//把越发基础的方法和成员写到Base类}// A类class A extends Base {// 返回两个数的差public int func1(int num1, int num2) {return num1 - num2;}}// 增加了一个新功效:完成两个数相加,然后和9求和class B extends Base {//如果B需要使用A类的方法,使用组合关系private A a = new A();public int func1(int a, int b) {return a + b;}public int func2(int a, int b) {return func1(a, b) + 9;}//我们仍然想使用A的方法public int func3(int a, int b) {return this.a.func1(a, b);}}public class Liskov {public static void main(String[] args) {// TODO Auto-generated method stubA a = new A();System.out.println("11-3=" + a.func1(11, 3));System.out.println("1-8=" + a.func1(1, 8));System.out.println("-----------------------");B b = new B();//因为B类不再继续A类,因此挪用者,不会再func1是求减法//挪用完成的功效就会很明确System.out.println("11+3=" + b.func1(11, 3));//这里本意是求出11+3System.out.println("1+8=" + b.func1(1, 8));// 1+8System.out.println("11+3+9=" + b.func2(11, 3));//使用组合仍然可以使用到A类相关方法System.out.println("11-3=" + b.func3(11, 3));// 这里本意是求出11-3}}这里解释一下,为什么这么做,首先继续一个公共的类Base,因为究竟是B类要在A类的基础上扩展功效,所以A类和B类性质是一样的,通过继续一个类,保证是同一性质的类,A和B继续一个公共的类,同时也保证利便举行多态挪用,使得A和B类扩展性变的很好。

淘汰继续的使用,防止开发者重写父类方法,破坏父类原有的功效,也防止如果对父类方法举行修改还要兼顾差别的子类。


本文关键词:通俗易懂,举例,解释,设计模式,原则,篇,亚博游戏娱乐平台

本文来源:亚博游戏娱乐平台-www.wxjgqg.com

相关产品推荐

在线客服 :

服务热线:056-748457627

电子邮箱: admin@wxjgqg.com

公司地址:云南省丽江市新会区人蒂大楼83号

亚博游戏娱乐平台在系统化的工作流程基础上,提供以工业设计为核心的品牌价值链整合服务,一站式服务内容包括:产品设计研究、产品差异化定位、工...

Copyright © 2006-2021 www.wxjgqg.com. 亚博游戏娱乐平台科技 版权所有