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

b87e7f5400bfc07f4036116d15173dc6.png

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) {
9
10        Vehicle vehicle = new Vehicle();
11
12        vehicle.run("汽车");
13
14        vehicle.run("摩托");
15
16        vehicle.run("飞机");
17
18    }
19
20}
21
22class Vehicle {
23
24    public void run(String vehicle) {
25
26        System.out.println(vehicle+"在公路上跑");
27    }
28}

方案二:

 1/** 2 3 * 方案二遵循单一职责原则 4 5 * 但是这样做的改动很大,即将类分解,同时修改客户端 6 7 * 改进:直接修改Vehicle类,改动的代码会比较少 8 9 */
10
11public class SingleResponsibility2 {
12
13    public static void main(String[] args) {
14
15        Vehicle1 vehicle1 = new Vehicle1();
16
17        vehicle1.run("汽车");
18
19        Vehicle2 vehicle2 = new Vehicle2();
20
21        vehicle2.run("轮船");
22
23        Vehicle3 vehicle3 = new Vehicle3();
24
25        vehicle3.run("飞机");
26    }
27
28}
29
30class Vehicle1{
31
32    public void run(String vehicle){
33
34        System.out.println(vehicle+"在地上跑");
35    }
36}
37
38class Vehicle2{
39
40    public void run(String vehicle){
41
42        System.out.println(vehicle+"在水上跑");
43    }
44
45}
46
47class Vehicle3{
48
49    public void run(String vehicle){
50
51        System.out.println(vehicle+"在天上跑");
52
53    }
54
55}

方案三:

 1/** 2 * 这种修改方法没有对原来的类做大的修改,只是增加方法 3 * 这里虽然没有在类这个级别上遵循单一职责原则,但是在方法级别上,仍然遵守这个原则 4 */
5
6public class SingleResonsibility3 {
7
8    public static void main(String[] args) {
9
10        Vehicle4 vehicle4 = new Vehicle4();
11
12        vehicle4.run("汽车");
13
14        vehicle4.run2("轮船");
15
16        vehicle4.run3("飞机");
17    }
18
19}
20
21class Vehicle4{
22
23    public void run(String vehicle){
24
25        System.out.println(vehicle+"在地上跑");
26
27    }
28
29    public void run2(String vehicle){
30
31        System.out.println(vehicle+"在水上跑");
32
33    }
34
35    public void run3(String vehicle) {
36
37        System.out.println(vehicle + "在天上跑");
38    }
39}

2.3 注意事项

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

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

  • 降低变更引起的风险;

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

3 接口隔离原则

3.1 什么是接口隔离原则

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

3.2 应用实例

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

620a264a317c4c628b0d19c95cc8127e.png

  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    }
100
101}
102
103class A {
104
105    public void depend1(Interface1 i) {
106
107        i.operation1();
108    }
109
110    public void depend2(Interface1 i) {
111
112        i.operation2();
113
114    }
115
116    public void depend3(Interface1 i) {
117
118        i.operation3();
119
120    }
121
122}
123
124class C {
125
126    public void depend1(Interface1 i) {
127
128        i.operation1();
129
130    }
131
132    public void depend4(Interface1 i) {
133
134        i.operation4();
135
136    }
137
138    public void depend5(Interface1 i) {
139
140        i.operation5();
141    }
142}

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

1a55320c40d3f5447039d94f2d1a5ab1.png

  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");
99
100    }
101
102}
103
104class A {
105
106    public void depend1(Interface1 i) {
107
108        i.operation1();
109
110    }
111
112    public void depend2(Interface2 i) {
113
114        i.operation2();
115
116    }
117
118    public void depend3(Interface2 i) {
119
120        i.operation3();
121
122    }
123
124}
125
126class C {
127
128    public void depend1(Interface1 i) {
129
130        i.operation1();
131
132    }
133
134    public void depend4(Interface3 i) {
135
136        i.operation4();
137
138    }
139
140    public void depend5(Interface3 i) {
141
142        i.operation5();
143
144    }
145
146}

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}
10
11class Email {
12
13    public String getInfo() {
14
15        return "电子邮件:Hello World!!!";
16    }
17}
18
19class Persion {
20
21    public void receive(Email e) {
22
23        System.out.println(e.getInfo());
24    }
25}

方案二:

 1/** 2 3 * 如果我们获取的对象是微信、短信等等,则新增类,同时Persion也要增加相应的接收方法 4 5 * 解决思路:引入一个抽象的接口IReceiver,表示接收者,这样Persion类与接口IReceiver发生依赖 6 7 * 因为Email、WeChat等等属于接收的范围,它们各自实现IReceiver接口就可以,这样我们就符合依赖倒转原则 8 9 */
10
11public class DependecyInversion2 {
12
13    public static void main(String[] args) {
14
15        Persion2 persion2 = new Persion2();
16
17        persion2.receive(new Email2());
18
19        persion2.receive(new WeChat());
20    }
21}
22
23interface IReceiver {
24
25    public String getInfo();
26}
27
28class Email2 implements IReceiver {
29
30    @Override
31    public String getInfo() {
32
33        return "电子邮件:Hello World!";
34    }
35}
36
37class WeChat implements IReceiver {
38
39    @Override
40    public String getInfo() {
41
42        return "微信消息:Hello weixin";
43    }
44}
45
46class Persion2 {
47
48    public void receive(IReceiver i) {
49
50        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}
11
12//实现接口
13class OpenAndColse implements IOpenAndClose {
14
15    @Override
16    public void opoen(ITV tv) {
17
18        tv.play();
19    }
20}
 1//方式二:构造方法传递
2interface IOpenAndClose {
3
4    public void open();//抽象方法
5}
6
7interface ITV {//ITV接口
8    public void play();
9}
10
11class OpenAndClose implements IOpenAndClose {
12
13    public ITV tv;//成员
14
15    public OpenAndClose(ITV tv) {//构造方法
16
17        this.tv = tv;
18    }
19
20    @Override
21    public void open() {
22
23        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}
11
12class OpenAndClose implements IOpenAndClose {
13
14    private ITV tv;
15
16    public void setTv(ITV tv) {
17
18        this.tv = tv;
19    }
20
21    @Override
22    public void open() {
23
24        this.tv.play();
25    }
26}

4.4 注意事项

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

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

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

END -

e461a4026817ced47d2d3bce79f6cbeb.png

a1fb757d39da7a1b79a88e4dc2ec54d3.png

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

因为我们可以跟电脑合作

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

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

db115dae6469f4b647bc748dc4e7907c.png 983b9265f21a2c56599921332c75459b.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值