Hello World 

当机会变得稀有,当竞争变得激烈

当方向不再清晰,当风口不再有风

关键词||设计模式

全文约7685字,细读大约需要20分钟

1 认识设计模式

1.1 什么是设计模式

所谓设计模式,就是对经常出现的软件设计问题的成熟解决方案。

很多人把设计模式想象成非常高深的概念,实际上设计模式仅仅是对特定问题的一种惯性思维。一些人喜欢抱着一本设计模式的书研究,以期成为一个“高手”,实际上设计模式的理解必须以足够的代码积累量作为基础,最好是经历过某种痛苦,或者正在经历一种苦痛,就会对设计模式有较深的感受。

1.2 设计模式的目的

编写软件的过程中,程序员面临着来自耦合性、内聚性以及可维护性、可扩展性、重用性、灵活性等多方面的挑战,设计模式是为了让程序拥有更好的:

  • 代码可重用性。相同功能的代码,不用多次编写;

  • 可读性。便于其他程序员的阅读和理解;

  • 可扩展性。当需要增加新功能时,非常方便;

  • 可靠性。当增加新的功能后,对原来的功能没有影响;

  • 使程序呈现高内聚、低耦合的特点。

1.3 什么是设计模式的原则?

设计模式原则,其实就是程序员在编程时,应当遵循的原则,也就是各种设计模式的基础,即设计模式为什么这样设计的依据。

设计模式的七大原则有:

  1. 单一职责原则

  2. 接口隔离原则

  3. 依赖倒置原则

  4. 里氏替换原则

  5. 开闭原则

  6. 迪米特法则

  7. 合成复用原则

2 单一职责原则

2.1 什么是单一职责原则

对类来说,一个类应该只负责一项职责。如类A负责两个不同职责:职责1,职责2,当职责1需求变更而改变类A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。

2.2 应用实例

方案一:

 1/** 2 * 方式一的run方法中,违反了单一职责原则, 3 * 解决的方案是根据交通工具运行方法不同,分解成不同类即可 4 */ 5 6public class SingleResponsebility1 { 7 8    public static void main(String[] args) { 910        Vehicle vehicle = new Vehicle();1112        vehicle.run("汽车");1314        vehicle.run("摩托");1516        vehicle.run("飞机");1718    }1920}2122class Vehicle {2324    public void run(String vehicle) {2526        System.out.println(vehicle+"在公路上跑");27    }28}

方案二:

 1/** 2 3 * 方案二遵循单一职责原则 4 5 * 但是这样做的改动很大,即将类分解,同时修改客户端 6 7 * 改进:直接修改Vehicle类,改动的代码会比较少 8 9 */1011public class SingleResponsibility2 {1213    public static void main(String[] args) {1415        Vehicle1 vehicle1 = new Vehicle1();1617        vehicle1.run("汽车");1819        Vehicle2 vehicle2 = new Vehicle2();2021        vehicle2.run("轮船");2223        Vehicle3 vehicle3 = new Vehicle3();2425        vehicle3.run("飞机");26    }2728}2930class Vehicle1{3132    public void run(String vehicle){3334        System.out.println(vehicle+"在地上跑");35    }36}3738class Vehicle2{3940    public void run(String vehicle){4142        System.out.println(vehicle+"在水上跑");43    }4445}4647class Vehicle3{4849    public void run(String vehicle){5051        System.out.println(vehicle+"在天上跑");5253    }5455}

方案三:

 1/** 2 * 这种修改方法没有对原来的类做大的修改,只是增加方法 3 * 这里虽然没有在类这个级别上遵循单一职责原则,但是在方法级别上,仍然遵守这个原则 4 */ 5 6public class SingleResonsibility3 { 7 8    public static void main(String[] args) { 910        Vehicle4 vehicle4 = new Vehicle4();1112        vehicle4.run("汽车");1314        vehicle4.run2("轮船");1516        vehicle4.run3("飞机");17    }1819}2021class Vehicle4{2223    public void run(String vehicle){2425        System.out.println(vehicle+"在地上跑");2627    }2829    public void run2(String vehicle){3031        System.out.println(vehicle+"在水上跑");3233    }3435    public void run3(String vehicle) {3637        System.out.println(vehicle + "在天上跑");38    }39}

2.3 注意事项

  • 降低类的复杂度,一个类只负责一项职责;

  • 提高类的可读性、可维护性;

  • 降低变更引起的风险;

  • 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才可以在代码级违反单一职责原则:只有类中方法数量足够少,可以在方法级别保存单一职责原则。

3 接口隔离原则

3.1 什么是接口隔离原则

客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。

3.2 应用实例

如图,类A通过接口Interface1依赖类B,类C通过接口Interface1依赖类D,如果接口Interface1对于类A和类C来说不是最小接口,那么类B和类D必须去实现他们不需要的方法。

  1public class Segregation1 {  2  3}  4  5//接口  6interface Interface1 {  7  8    void operation1();  9 10    void operation2(); 11 12    void operation3(); 13 14    void operation4(); 15 16    void operation5(); 17 18} 19 20class B implements Interface1 { 21 22    @Override 23 24    public void operation1() { 25 26        System.out.println("B实现了operation1"); 27    } 28 29    @Override 30 31    public void operation2() { 32 33        System.out.println("B实现了operation2"); 34    } 35 36    @Override 37 38    public void operation3() { 39 40        System.out.println("B实现了operation3"); 41 42    } 43 44    @Override 45 46    public void operation4() { 47 48        System.out.println("B实现了operation4"); 49    } 50 51    @Override 52 53    public void operation5() { 54 55        System.out.println("B实现了operation5"); 56    } 57 58} 59 60class D implements Interface1 { 61 62    @Override 63 64    public void operation1() { 65 66        System.out.println("D实现了operation1"); 67 68    } 69 70    @Override 71 72    public void operation2() { 73 74        System.out.println("D实现了operation2"); 75 76    } 77 78    @Override 79 80    public void operation3() { 81 82        System.out.println("D实现了operation3"); 83 84    } 85 86    @Override 87 88    public void operation4() { 89 90        System.out.println("D实现了operation4"); 91    } 92 93    @Override 94 95    public void operation5() { 96 97        System.out.println("D实现了operation5"); 98 99    }100101}102103class A {104105    public void depend1(Interface1 i) {106107        i.operation1();108    }109110    public void depend2(Interface1 i) {111112        i.operation2();113114    }115116    public void depend3(Interface1 i) {117118        i.operation3();119120    }121122}123124class C {125126    public void depend1(Interface1 i) {127128        i.operation1();129130    }131132    public void depend4(Interface1 i) {133134        i.operation4();135136    }137138    public void depend5(Interface1 i) {139140        i.operation5();141    }142}

按隔离原则应当这样处理:将接口Interface1拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。

  1public class Segregation2 {  2  3    public static void main(String[] args) {  4  5        A a = new A();  6  7        a.depend1(new B());  8  9        a.depend2(new B()); 10 11        a.depend3(new B()); 12 13        C c = new C(); 14 15        c.depend1(new D()); 16 17        c.depend4(new D()); 18 19        c.depend5(new D()); 20 21    } 22 23} 24 25//接口 26interface Interface1 { 27 28    void operation1(); 29 30} 31 32interface Interface2 { 33 34    void operation2(); 35 36    void operation3(); 37 38} 39 40interface Interface3 { 41 42    void operation4(); 43 44    void operation5(); 45 46} 47 48class B implements Interface1, Interface2 { 49 50    @Override 51 52    public void operation1() { 53 54        System.out.println("B实现了operation1"); 55 56    } 57 58    @Override 59 60    public void operation2() { 61 62        System.out.println("B实现了operation2"); 63 64    } 65 66    @Override 67 68    public void operation3() { 69 70        System.out.println("B实现了operation3"); 71 72    } 73 74} 75 76class D implements Interface1, Interface3 { 77 78    @Override 79 80    public void operation1() { 81 82        System.out.println("D实现了operation1"); 83 84    } 85 86    @Override 87 88    public void operation4() { 89 90        System.out.println("D实现了operation4"); 91 92    } 93 94    @Override 95 96    public void operation5() { 97 98        System.out.println("D实现了operation5"); 99100    }101102}103104class A {105106    public void depend1(Interface1 i) {107108        i.operation1();109110    }111112    public void depend2(Interface2 i) {113114        i.operation2();115116    }117118    public void depend3(Interface2 i) {119120        i.operation3();121122    }123124}125126class C {127128    public void depend1(Interface1 i) {129130        i.operation1();131132    }133134    public void depend4(Interface3 i) {135136        i.operation4();137138    }139140    public void depend5(Interface3 i) {141142        i.operation5();143144    }145146}

4 依赖倒转原则

4.1 什么是依赖倒转原则

依赖倒转原则是指高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象;依赖倒转的中心思想是面向接口编程。

依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在java中,抽象指的是接口或者抽象类,细节就是具体的实现类。

使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。

4.2 应用实例

请编程完成persion接收消息的功能。

方案一:

 1public class DependecyInversion { 2 3    public static void main(String[] args) { 4 5        Persion persion = new Persion(); 6 7        persion.receive(new Email()); 8    } 9}1011class Email {1213    public String getInfo() {1415        return "电子邮件:Hello World!!!";16    }17}1819class Persion {2021    public void receive(Email e) {2223        System.out.println(e.getInfo());24    }25}

方案二:

 1/** 2 3 * 如果我们获取的对象是微信、短信等等,则新增类,同时Persion也要增加相应的接收方法 4 5 * 解决思路:引入一个抽象的接口IReceiver,表示接收者,这样Persion类与接口IReceiver发生依赖 6 7 * 因为Email、WeChat等等属于接收的范围,它们各自实现IReceiver接口就可以,这样我们就符合依赖倒转原则 8 9 */1011public class DependecyInversion2 {1213    public static void main(String[] args) {1415        Persion2 persion2 = new Persion2();1617        persion2.receive(new Email2());1819        persion2.receive(new WeChat());20    }21}2223interface IReceiver {2425    public String getInfo();26}2728class Email2 implements IReceiver {2930    @Override31    public String getInfo() {3233        return "电子邮件:Hello World!";34    }35}3637class WeChat implements IReceiver {3839    @Override40    public String getInfo() {4142        return "微信消息:Hello weixin";43    }44}4546class Persion2 {4748    public void receive(IReceiver i) {4950        System.out.println(i.getInfo());51    }52}

4.3 依赖传递的三种方式

接口传递、构造方法传递、setter方法传递。

 1//第一种方式:接口传递 2//开关的接口 3interface IOpenAndClose { 4 5    public void opoen(ITV tv);//抽象方法,接收接口 6} 7 8interface ITV {//ITV接口 9    public void play();10}1112//实现接口13class OpenAndColse implements IOpenAndClose {1415    @Override16    public void opoen(ITV tv) {1718        tv.play();19    }20}
 1//方式二:构造方法传递 2interface IOpenAndClose { 3 4    public void open();//抽象方法 5} 6 7interface ITV {//ITV接口 8    public void play(); 9}1011class OpenAndClose implements IOpenAndClose {1213    public ITV tv;//成员1415    public OpenAndClose(ITV tv) {//构造方法1617        this.tv = tv;18    }1920    @Override21    public void open() {2223        this.tv.play();24    }25}
 1//方式三:setter方法传递 2interface IOpenAndClose { 3 4    public void open();//抽象方法 5} 6 7interface ITV {//ITV接口 8 9    public void play();10}1112class OpenAndClose implements IOpenAndClose {1314    private ITV tv;1516    public void setTv(ITV tv) {1718        this.tv = tv;19    }2021    @Override22    public void open() {2324        this.tv.play();25    }26}

4.4 注意事项

底层模块尽量都要有抽象类或接口,或者两者都有,程序稳定性更好。

变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象间,就存在一个缓冲层,利于程序扩展和优化。

继承时要遵循里氏替换原则。

END -

在电脑飞速发展的时代 丨我们不应该感到恐惧

因为我们可以跟电脑合作

成为一个人马合一、人枪合一、人电脑合一的新物种

这样的人才是这个时代的超级个体

代码规范七大原则_设计模式的七大原则详解||上篇相关推荐

  1. 接口隔离原则_设计模式之七大设计原则(上)

    这是雷总20多年前写的汇编程序,像诗一样优雅 而中国诗词讲究平仄.押韵.对仗等一系列的规则原则, 那么想要写出像诗一样优雅的程序你不得不知的 -- 设计模式之七大原则: 1.开闭原则:对修改关闭,对扩 ...

  2. 设计模式六大原则_设计模式—设计六大原则

    1. 单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因. 从这句定义我们很难理解它的含义,通俗讲就是我们不要让一个类承担过多的职责.如果一个类承担的职责过多,就等于把这些职责耦 ...

  3. java solid设计原则_设计模式之SOLID原则

    什么是SOLID原则 SOLID = SRP(职责单一原则) + OCP(对扩展开发,修改关闭原则)+ LSP(里氏替换原则)+ ISP(接口隔离原则)+ DIP(依赖反转原则) SRP: Singl ...

  4. 依赖倒置原则_设计模式之SOLID原则

    在程序设计领域, SOLID(单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期引入,指代了面向对象编程和面向对象设计的五个基本原则.当这些原则被一起应用时,它们使 ...

  5. java 肌汉模式_设计模式之原型模式详解(附源代码)

    原型模式(Prototype Pattern) 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. ...

  6. 数学建模_随机森林分类模型详解Python代码

    数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...

  7. 设计模式之模板方法模式详解

    设计模式之模板方法模式详解 概述 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的 ...

  8. 设计模式之桥接模式详解

    设计模式之桥接模式详解 文章目录 设计模式之桥接模式详解 一.什么是桥接模式 二.桥接模式的应用场景 三.桥接模式的角色组成 四.桥接模式通用写法示例 五.桥接模式优缺点 一.什么是桥接模式 桥接模式 ...

  9. 设计模式之策略模式详解

    设计模式之策略模式详解 概述 先看下面的图片,我们去旅游选择出行模式有很多种,可以骑自行车.可以坐汽车.可以坐火车.可以坐飞机. 作为一个程序猿,开发需要选择一款开发工具,当然可以进行代码开发的工具有 ...

最新文章

  1. python自动发送微信公众号_使用python一步一步搭建微信公众平台(四)----将小黄鸡引入微信自动回复...
  2. 数字图像处理——第五章 图像复原
  3. python实现换位加密算法
  4. 高通qcc芯片天梯图_芯片性能天梯榜“爆冷”,骁龙888无法撼动麒麟9000的王位...
  5. 单例模式 代码以及祥解
  6. EMC测试仪器_智芯文库 | 单片机系统EMC测试和故障排除
  7. python聊天机器人
  8. 在业务控制方法中写入普通变量收集参数
  9. 快手通过标签添加好友_快手开通直播权限添加垂直标签
  10. BZOJ-4706 B君的多边形 OEIS
  11. Ubuntu录制gif动态图
  12. C语言全局变量和局部变量的区别详解
  13. 啊哈算法之水管工游戏
  14. 经验分享:兢兢业业工作5年的我不敌半年新人,原来“迪赛智慧数”才是升职加薪的关键!
  15. 分数阶 计算机应用,分数阶计算器
  16. SqlServer 汉字转换拼音首字母函数
  17. [转]Magento 2 and 1 Million Products
  18. 迁移学习的使用技巧和在不同数据集上的选择
  19. 06.破解Windows7密码
  20. 前端埋点设计/小程序+友盟埋点方案

热门文章

  1. 在Linux下巧下载
  2. 华为路由交换常见配置
  3. css中的 font 与 font-size
  4. Excel之【保护工作表】功能(工具----保护) ------可以防止修改格式,删除行。只能在里面填写数据。
  5. xampp中apache点击启动失败解决方法
  6. WIN10安装VS2013出现兼容性问题解决
  7. mysql修改root密码及修改密码过程中报错的解决方案
  8. 将input file的选择的文件清空的两种解决方案
  9. 如何让jQuery执行同步而不是异步的Ajax请求?
  10. 您如何合并两个Git存储库?