读书笔记----软件设计原则、设计模式
| 这个作业属于哪个课程 | <2022软件代码开发技术> |
|---|---|
| 这个作业要求在哪里 | <读书笔记----软件设计原则、设计模式> |
| 这个作业的目标 | 1.鼓励阅读和培养自学习惯 2.理解并掌握软件设计原则、设计模式 3.思考软件开发中设计原则、设计模式的应用 |
书籍详情
| 书名 | 软件设计模式 |
|---|---|
| 作者 | 朱洪军 |
| ISBN | 9787115489760 |
| 出版社 | 人民邮电出版社 |
| 出版时间 | 2018年10月 |
一、读书总结
- 整体总结
本书正文共六章,主要讲解软件设计原则和设计模式。第一章首先讲解学习基础,包括软件工程、面向对象和UML的相关知识;第二章讲解面向对象程序设计原则;第三至六章详细讲解设计模式。以下概括书中提及的设计原则和设计模式。 - 设计原则
- 单一职责原则
每个类或模块应只承担一个业务职责。当一个类承担的业务职责较多时,任何职责需求的变化都会引起类的变化,导致代码不稳定,代码修复的代价也会变高。职责划分清晰,不仅可以提高代码可读性,还能够降低出错风险,降低维护成本。 - 开放/闭合原则
对扩展是开放的,对修改是关闭的。当业务需求变化时,在不修改已有的代码的基础上通过扩展很容易地实现。软件代码的业务逻辑充满耦合,代码的修改可能会制造出新的代码缺陷,进行软件设计时应鼓励扩展、减少修改。 - 接口隔离原则
客户端不依赖不需实现的接口,一个类对另一个类的依赖应该建立在最小的接口上。强调接口的细化,不要对接口添加不必要的职责,符合高内聚低耦合的思想。 - 依赖倒置原则
类不是孤立的,一个类需要依赖于其他类来协作完成工作。这种依赖不应该是具体实现,而应该依赖抽象。遵循依赖倒置原则会大大提高系统的灵活性,类只需关心特定契约(抽象),可以在最大限度地降低影响的基础上轻松而快速地修改功能。 - Liskov替换原则
子类可以替换任何基类能够出现的地方,替换后代码正常工作。子类可以扩展父类的功能,但不能改变父类原有的功能。在继承体系中,子类中可以增加自己特有的方法,也可以实现父类的抽象方法,但是不能重写父类的非抽象方法。
- 单一职责原则
- 设计模式
- 分类概览
![]()
- 常用设计模式
- 单例模式
保证一个类只有一个实例,该实例必须由单例类自行创建(构造器私有),并且提供一个访问该实例的全局访问点。由于只生成一个实例,减少了系统性能开销,避免对资源的多重占用。
![]()
- 工厂模式
工厂顾名思义就是创建产品,在软件设计中就是实例化对象,用工厂方法代替new对象。定义一个创建对象的接口,将实际创建工作推迟到子类当中。该模式用于封装和管理对象的创建,优点如下:- 一个调用者想创建一个对象,只需知道其名称;
- 屏蔽产品的具体实现,调用者只关心产品的接口;
- 将创建对象的工作转移到子类中,将调用者与实现类解耦;
- 扩展性高,可以使系统在不修改具体工厂角色的情况下引进新的产品。
![]()
- 单例模式
- 分类概览
二、读书心得
- 单例模式深挖
单例模式作为常用的设计模式之一,常用于需要控制实例数目,节省系统资源的场景。单例模式的实现有多种方式,主要是饿汉式和懒汉式。- 饿汉式:线程安全且调用效率高,但不能延时加载;
public class SingletonDemo01 { //若不使用会浪费资源 private static SingletonDemo01 s = new SingletonDemo01();//立即加载 private SingletonDemo01() {//构造器私有 } //方法没有同步,调用效率高 public static SingletonDemo01 getInstance() { return s; } } - 懒汉式:线程安全,调用效率不高,但可以延时加载。
public class SingletonDemo02 { private static SingletonDemo02 s; private SingletonDemo02() { } public static synchronized SingletonDemo02 getInstance() { if(s==null) {//延时加载,资源利用率高,但并发效率低 s = new SingletonDemo02(); } return s; } } - 多线程环境下效率测试
运行结果:饿汉式18ms,懒汉式108ms。多次更改创建实例的数量,可以看出在多线程环境下懒汉式的运行时间一般比饿汉式时间高一到两个数量级。在加载时不浪费较多资源的情况下,建议使用饿汉式,在多线程环境下较为有利。import java.util.concurrent.CountDownLatch; public class Client { public static void main(String[] args) throws Exception{ long start = System.currentTimeMillis(); int threadNum = 10; final CountDownLatch countDownLatch = new CountDownLatch(threadNum); for(int i=0; i<threadNum; i++) { new Thread(new Runnable() { public void run() { for(int j=0; j<1000000; j++) { //饿汉式测试,改为SingletonDemo2即是懒汉式测试 Object o = SingletonDemo01.getInstance(); } countDownLatch.countDown();//计数器减一 } }).start(); } countDownLatch.await();//main线程阻塞,直到计数器变为0,才会继续往下执行。 long end = System.currentTimeMillis(); System.out.println("总耗时:"+(end - start)); } }
- 饿汉式:线程安全且调用效率高,但不能延时加载;
- 开发实践回顾
学习软件设计原则和模式后,回想以往的开发实践经历,我深有感触,其中感触最深的应该是单一职责原则。面对软件开发项目,我更多考虑的是如何实现功能需求,代码设计完全违反单一职责原则,在后续需求添加时无法实现,甚至倒逼需求减少。除此之外,我意识到单例模式和工厂模式在web开发的应用。实际开发的系统一般都很复杂,比如在开发在线考试系统时,需要设计的类有Student、Question、Exam等,相应的Dao层需要有StudentDao、QuestionDao和ExamDao,系统中StudentDao等的使用非常频繁,可使用工厂模式+单例模式(饿汉式)的方式进行管理。public class DaoFactory { private static DaoFactory factory = new DaoFactory(); private Map<String, Object> map = new ConcurrentHashMap<>(); private DaoFactory(){} public static DaoFactory getInstance() { return factory; } // 返回有关学生操作的对象,后续可类似增加问题和考试操作的对象 public StudentDao getStudentDao() { StudentDao dao = (StudentDao) map.get("StudentDao"); if (dao != null) { return dao; } else { dao = new StudentDao(); map.put("StudentDao", dao); } return dao; } } //后续获取StudentDao对象 StudentDao studentDao = DaoFactory.getInstance().getStudentDao(); - 个人认识总结
我们学习的这些软件设计原则和设计模式,其使用目的都是让软件项目更加易于扩展和维护,其实现依赖的就是一个手段————分工。在进行软件设计时,面对系统需求,我们的任务其实就是合理地设计类或模块完成一定的职责,这些类与模块相互协作就构成了我们需要的软件系统,这个过程其实就是分工。在软件项目规模越来越大的今天,合理地使用这些前人总结的设计原则和模式进行软件设计,秉持高内聚低耦合的思想,类或模块的分工尽可能细化,软件系统的开发将事半功倍。虽然通过阅读书籍了解了这些软件设计原则和设计模式,但是纸上得来终觉浅,在后续的开发实践中的合理运用任重而道远。
三、相关截图





浙公网安备 33010602011771号