设计模式
设计模式
统一过程(UP)
统一过程(Unified Process,简称UP)是一种软件开发过程框架,它是一种迭代的、增量的开发方法,旨在帮助开发团队更好地管理软件项目。
统一过程的主要特点包括:
- 迭代开发:将整个项目分解为多个迭代周期,每个周期完成一定的功能模块,逐步构建完整的软件系统。
- 增量交付:在每个迭代周期结束时,交付一个可运行的软件版本,以便客户和用户能够及时了解项目进展并提供反馈。
- 风险管理:通过持续评估项目中的风险,并在必要时进行调整,确保项目按计划进行。
- 适应性:根据项目需求和团队经验,可以调整统一过程的各个方面,以适应不同的项目场景。
- 文档化:在整个开发过程中,保持对软件设计、实现和测试的详细记录,以便团队成员之间共享信息并确保项目的可维护性。
代码质量的评价标准
代码质量:
1、可维护性 :不去破坏原有的代码设计以及不引入新的bug的前提下,修改或者新增代码
2、灵活性 :在添加新代码的时候,不破坏资深的前提下接纳新代码。
3、简洁性:别人理解时间最小化。
4、可复用性:减少重复代码编写,复用已有的代码
5、可测试性 :在单元测试的时候易于测试。
6、可扩展性:对修改关闭,对扩展开放,不修改或者少量修改代码增添新功能。
7、可读性:人类能理解的代码。代码风格符合编程规范。
编程方法论
1、面向对象:是一种编程的思想也是一种编程范式
2、设计原则:一些代码设计的经验总结,尽量根据设计原则来开发。
- 单一职责原则
- 开闭原则
- 里氏代换原则
- 依赖倒转原则
- 接口隔离原则
- 迪米特法则
3、设计模式:已经总结出来的一套解决方案或者设计思路
4、编程规范:解决代码可读性问题,更加偏重代码细节。
5、重构:不改变代码外部行为的情况下修改代码。
设计模式概述
什么是设计模式:就是已经一套已经被反复使用,多人知晓的套路。
好处:能够读懂源码,学习框架事半功倍。
设计模式分类
GoF设计模式有23个,根据用途分为三类:创建型、结构性、行为型
创建型(5种)
提供创建对象的机制,提升已有代码的灵活性和可复用性
常用:单例模式、工厂模式(工厂方法和抽象工厂)、建造者模式
不常用:原型模式
结构性模式(7种)
介绍如何将对象和类祖冲较大的结构,并同时保持结构的灵活和高效
常用:代理、桥接、装饰、适配器
不常用:外观、组合、享元
行为模式(11种)
负责对象间的高效沟通和职责传递的委派
常用:观察者模式、模板模式、策略模式、责任链模式、迭代器模式、状态模式
不常用:访问者模式、备忘录模式、命令模式、解释器模式、中介模式。
UML图概述
统一建模语言,用来设计软件的可视化建模语言
UML分类
静态结构图:类图、对象图、组件图、部署图
动态行为图:状态图、活动图、时序图、协作图、组件图。
类图
反映的是类结构和类之间的关系为目的。
类结构表示法
如果是抽象类,类名和方法名要用斜体来表示
接口类的话
类关系的表示方法
实现关系:
泛化关系:
关联关系:
聚合关系:
组合关系:
依赖关系:
多用组合少用继承。
活动图
交互图(顺序图+通信图)
顺序图
通信图
组件图
包图
状态图
部署图
六大设计原则
简称为SOLID
单一职责原则
一个类或者模块只实现一个功能。不要设计大而全的类。设计功能单一的类。(要根据实际业务场景分析)
开放封闭原则
对扩展开放、对修改关闭
当增添新的需求我们应该是扩展而不是修改
里氏替换原则
什么是替换?
如果方法的参数是一个接口类型,这个方法可以接受所有实现过这个接口的实现类(多态)
与期望行为一致的替换:在不了解派生类的情况下,进通过接口或者基类的方法,即可清楚的知道方法的行为,而不管那种派生类的视线,都与接口或基类方法的期望行为一致。
例子:
Context是调用类
接口隔离原则
一个类对另一个类的依赖应该建立在最小的接口上
通俗解释:要为各个类建立他们需要的专用接口,而不要视图去建立一个很庞大的接口供所有依赖他的类去调用。
例子:
依赖倒置原则
在软件设计中要以抽象为基础搭建起来的架构。
案例:
如果是这样设计,用户就只能用那一种类型的配件了,想要替换很麻烦,所以如果用依赖倒置原则来设计
迪米特法则
不该有直接依赖关系的类之间,不要有依赖,有依赖的类之间,依赖必要的接口。
多使用中间人。
案例:
创建型模式(5种)
这类模式提供创建对象的机制,能够提升已有代码的灵活性和复用性
- 常用的有:单例模式、工厂模式、建造者模式
- 不常用的有:原型模式。
单例设计模式
只有一个实例对外提供服务,而这个类被称为单例类。
使用单例模式要做的两件事
1、保证一个类只有一个实例
2、为该实例提供一个全局访问点
单例模式结构
单例模式之饿汉式
在类加载期间初始化私有的静态实例,保证instance实例创建过程是线程安全的。
特点:不支持延时加载,获取实例对象的速度比较快,但是如果对象比较大,而且一致没有使用就会造成内存的浪费。
1 | public class Singleton_01{ |
测试类
1 | public class Test{ |
单例模式之懒汉式(线程不安全)
特点:支持延时加载,只有调用getInstance方法时,才会创建对象。
当高并发的时候不能保证只有一个实例
1 | public class Singleton_02{ |
不能保证单例的原因
懒汉式如何保证线程安全
1 | public class Singleton_03{ |
使用synchronzied锁,锁住创建单例对象的方法,防止多个线程同时调用。
缺点:因为对getInstance()方法加了锁,导致并发度很低。
单例模式-双重校验
1 | public class Singleton_04{ |
单例模式-静态内部类
根据静态内部类的特性,同时解决了 延时加载 现成安全的问题 并且代码更加简洁。
1 | public class Singleton_05{ |
反射对于单例的破坏
1 | public class Test_Reflect{ |
如何解决反射对于单例的破坏?
1 | public class Singleton_05{ |
序列化对于单例的破坏
解决方法:在单例类中定义readResolve方法,就可以解决序列化对单例的破坏。
为什么是这样解决?因为通过读源码的过程中得知,序列化和反序列化的过程中,程序会判断是否有readResolve方法,如果有就执行该方法,否则就会创建一个新的对象。
单例模式-枚举方式
1 | public enum Singleton_06{ |
可以阻止反射的破坏:在反射方法中不允许使用反射创建枚举对象
可以阻止序列化的破坏:在序列化的时候仅仅将枚举对象的name属性输出到了结果中,反序列化的时候,就会通过Enum的valueOf方法,来根据名字取查找对应的枚举对象。
单例模式总结
工厂模式
在工程模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且通过使用一个公共的接口来指向新创建的对象。
简单工厂被分成了三种:简单工厂,工厂方法,抽象工厂。
工厂模式——原始实现方式1
案例:模拟发放奖品业务
首先是最原始的实现方式不适用设计模式的方法进行开发
这些是实体类
简单工厂模式
简单工厂不是一种设计模式,它是通过使用静态方法接受不同的参数来返回不同的实例对象(多态)
实现方式:定义一个工厂类,根据传入的参数不同返回不同的实例,被创建的实例具有共同的父类或接口。
简单工厂包含:
1、抽象产品
2、具体产品
3、具体工厂
这样子设计是有问题的
不符合开闭原则,没有扩展性。
工厂方法模式
概念:定义一个用于创建对象的接口,让子类决定实例化哪个 产品类对象。工厂方法使一个产品类的实例化延迟到其工厂的子类。
但是这个还是有个小问题就是在工厂类中还是用ifelse来判断生产对象。
可以设计一个工厂的工厂,在工厂的工厂类里面专门进行逻辑判断,这样就符合了开闭原则。
抽象工厂模式
抽象工厂模式中,每一个具体工厂都提供了多个工厂方法,用于生产多种不同类型的产品,这些产品构成一个产品族,
建造者模式
定义:将一个复杂对象的构建和表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式原理:
案例:
问题二:当一个方法需要传入多个参数的时候,如何重构。
原型模式
原型模式:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。
原型模式主要解决的问题:
原型模式结构图
浅克隆和深克隆
浅克隆:克隆对象中的所有变量的值与原型对象的值完全相同(引用数据类型变量中存储的地址也是完全一致的)
深克隆:克隆对象的所有基本数据类型变量含有的值与原型对象完全一致(不包含引用数据类型)。
例子:
模拟某银行电子账单系统的广告信发送功能,广告信的发送都是有一个模板的,从数据库查出客户的信息,然后放到模板中生成一份完整的右键,然后交给发送机进行发送处理。
发送广告邮件UML类图
结构型模式(7种)
一共有7种:代理模式、桥接模式、装饰着模式、适配器模式、门面(外观)模式、组合模式、享元模式。
代理模式
让你能够提供对象的代替品或其占位符。代理控制着对于源对象的访问,并允许将请求提交给对象前后进行一些处理。
桥接模式
将抽象部分与实现部分分离,使他们都可以独立的变化。
装饰模式
享元模式
组合模式
适配器模式
·