设计模式七大原则解读(三)

简介: 设计模式七大原则解读(三)

改进方法

通用的做法是:原来的父类和子类都继承一个更通俗的基类,原有的继承关系去掉,采用依赖,聚合,组合等关系代替

1. public class Liskov {
2. public static void main(String[] args) {
3. // TODO Auto-generated method stub
4. A a = new A();
5.         System.out.println("11-3=" + a.func1(11, 3));
6.         System.out.println("1-8=" + a.func1(1, 8));
7.         System.out.println("-----------------------");
8. B b = new B();
9. //因为 B 类不再继承 A 类,因此调用者,不会再 func1 是求减法
10. //调用完成的功能就会很明确
11.         System.out.println("11+3=" + b.func1(11, 3));//这里本意是求出 11+3
12.         System.out.println("1+8=" + b.func1(1, 8));// 1+8
13.         System.out.println("11+3+9=" + b.func2(11, 3));
14. //使用组合仍然可以使用到 A 类相关方法
15.         System.out.println("11-3=" + b.func3(11, 3));// 这里本意是求出 11-3
16.     }
17. }
18. //创建一个更加基础的基类
19. class Base {
20. //把更加基础的方法和成员写到 Base 类
21. }
22. // A 类
23. class A extends Base {
24. // 返回两个数的差
25. public int func1(int num1, int num2) {
26. return num1 - num2;
27.     }
28. }
29. // B 类继承了 A
30. // 增加了一个新功能:完成两个数相加,然后和 9 求和
31. class B extends Base {
32. //如果 B 需要使用 A 类的方法,使用组合关系
33. private A a = new A();
34. //这里,重写了 A 类的方法, 可能是无意识
35. public int func1(int a, int b) {
36. return a + b;
37.     }
38. public int func2(int a, int b) {
39. return func1(a, b) + 9;
40.     }
41. //我们仍然想使用 A 的方法
42. public int func3(int a, int b) {
43. return this.a.func1(a, b);
44.     }
45. }

开闭原则

基本介绍

1) 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

2) 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。
3) 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
4) 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。

代码引进

看一个画图形的功能

1. public class Ocp {
2. public static void main(String[] args) {
3. //使用看看存在的问题
4. GraphicEditor graphicEditor = new GraphicEditor();
5.         graphicEditor.drawShape(new Rectangle());
6.         graphicEditor.drawShape(new Circle());
7.         graphicEditor.drawShape(new Triangle());
8.     }
9. }
10. 
11. //这是一个用于绘图的类 [使用方]
12. class GraphicEditor {
13. //接收 Shape 对象,然后根据 type,来绘制不同的图形
14. public void drawShape(Shape s) {
15. if (s.m_type == 1)
16.             drawRectangle(s);
17. else if (s.m_type == 2)
18.             drawCircle(s);
19. else if (s.m_type == 3)
20.             drawTriangle(s);
21.     }
22. 
23. //绘制矩形
24. public void drawRectangle(Shape r) {
25.         System.out.println(" 绘制矩形 ");
26.     }
27. 
28. //绘制圆形
29. public void drawCircle(Shape r) {
30.         System.out.println(" 绘制圆形 ");
31.     }
32. 
33. //绘制三角形
34. public void drawTriangle(Shape r) {
35.         System.out.println(" 绘制三角形 ");
36.     }
37. }
38. 
39. //Shape 类,基类
40. class Shape {
41. int m_type;
42. }
43. 
44. class Rectangle extends Shape {
45.     Rectangle() {
46. super.m_type = 1;
47.     }
48. }
49. 
50. class Circle extends Shape {
51.     Circle() {
52. super.m_type = 2;
53.     }
54. }
55. //新增画三角形
56. class Triangle extends Shape {
57.     Triangle() {
58. super.m_type = 3;
59.     }
60. }

方式 1 的优缺点

1) 优点是比较好理解,简单易操作。
2) 缺点是违反了设计模式的 ocp 原则,即对扩展开放(提供方),对修改关闭(使用方)。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码.
3) 比如我们这时要新增加一个图形种类 三角形,我们需要做如下修改,修改的地方较多

改进方法

思路:把创建 Shape 类做成抽象类,并提供一个抽象的 draw 方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承 Shape,并实现 draw 方法即可,使用方的代码就不需要修 -> 满足了开闭原则

1. public class Ocp {
2. public static void main(String[] args) {
3. //使用看看存在的问题
4. GraphicEditor graphicEditor = new GraphicEditor();
5.         graphicEditor.drawShape(new Rectangle());
6.         graphicEditor.drawShape(new Circle());
7.         graphicEditor.drawShape(new Triangle());
8.         graphicEditor.drawShape(new OtherGraphic());
9.     }
10. }
11. 
12. //这是一个用于绘图的类 [使用方]
13. class GraphicEditor {
14. //接收 Shape 对象,调用 draw 方法
15. public void drawShape(Shape s) {
16.         s.draw();
17.     }
18. }
19. 
20. //Shape 类,基类
21. abstract class Shape {
22. int m_type;
23. 
24. public abstract void draw();//抽象方法
25. }
26. 
27. class Rectangle extends Shape {
28.     Rectangle() {
29. super.m_type = 1;
30.     }
31. 
32. @Override
33. public void draw() {
34. // TODO Auto-generated method stub
35.         System.out.println(" 绘制矩形 ");
36.     }
37. }
38. 
39. class Circle extends Shape {
40.     Circle() {
41. super.m_type = 2;
42.     }
43. 
44. @Override
45. public void draw() {
46. // TODO Auto-generated method stub
47.         System.out.println(" 绘制圆形 ");
48.     }
49. }/新增画三角形
50. 
51. class Triangle extends Shape {
52.     Triangle() {
53. super.m_type = 3;
54.     }
55. 
56. @Override
57. public void draw() {
58. // TODO Auto-generated method stub
59.         System.out.println(" 绘制三角形 ");
60.     }
61. }
62. 
63. //新增一个图形
64. class OtherGraphic extends Shape {
65.     OtherGraphic() {
66. super.m_type = 4;
67.     }
68. 
69. @Override
70. public void draw() {
71. // TODO Auto-generated method stub
72.         System.out.println(" 绘制其它图形 ");
73.     }
74. }

迪米特法则

基本介绍

1) 一个对象应该对其他对象保持最少的了解
2) 类与类关系越密切,耦合度越大
3) 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息
4) 迪米特法则还有个更简单的定义:只与直接的朋友通信

直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

相关文章
|
2天前
|
设计模式 前端开发 Java
设计模式之六大基本原则
设计模式之六大基本原则
20 0
|
6月前
|
设计模式 Java 程序员
|
7月前
|
设计模式 Java 测试技术
Java设计模式七大原则-接口隔离原则
Java设计模式七大原则-接口隔离原则
42 0
|
2天前
|
设计模式 算法 架构师
【搞懂设计模式】设计模式与面向对象原则
【搞懂设计模式】设计模式与面向对象原则
6 1
|
2天前
|
设计模式 前端开发 API
写出易维护的代码|React开发的设计模式及原则
本文对React社区里出现过的一些设计模式进行了介绍,并讲解了他们遵循的设计原则。
|
2天前
|
设计模式 数据可视化 关系型数据库
设计之美-揭秘设计模式、原则与UML的魔法
设计模式、设计原则和UML是软件工程设计中的核心要素。设计模式为常见问题提供经验证的解决方案,复用性高且提升开发效率。设计原则指导我们创建灵活、可维护和可扩展的系统,确保代码质量和长期可维护性。UML(统一建模语言)则是一种强大的可视化工具,用于描述、构建和文档化软件系统的结构和行为。它帮助开发者更清晰地理解系统架构和组件间关系。综合应用设计模式、设计原则和UML,能够显著提高软件开发的效率和质量,减少维护成本,为复杂系统的设计和实施提供有力支持。
37 0
设计之美-揭秘设计模式、原则与UML的魔法
|
2天前
|
设计模式 关系型数据库
设计模式的六大原则:理解设计模式的关键思想和应用
设计模式的六大原则:理解设计模式的关键思想和应用
18 2
|
2天前
|
设计模式
【设计模式】1、设计模式七大原则
【设计模式】1、设计模式七大原则
19 0
|
2天前
|
设计模式 存储 NoSQL
【设计模式】软件设计原则-单一职责原则
【1月更文挑战第12天】【设计模式】软件设计原则-单一职责原则
|
2天前
|
设计模式 关系型数据库
【设计模式】软件设置原则-开闭原则
【1月更文挑战第12天】【设计模式】软件设置原则-开闭原则