学习汇总帖,内容全面而宽泛,粒度粗,具体的内容学习细节内容,后期会贴上别人的研究链接,以供参考。
文中的简单理解,为本人的浅显理解,无法和大佬的理解和表述相提并论,如果大佬愿意指导,请您在留言区莅临指导,定当及时改正错误,谢谢大佬。
设计原则汇总
实现原则,高内聚低耦合。
- 1、单一职责原理
原则上:属性业务分离,实际情况,接口上职责单一,类的设计,负责的内容细分详细 - 2、里氏替换原则
只要父类能出现的地方,子类就已经能出现,反之则不行 - 3、依赖倒置原则
高层模块不应该依赖底层模块,而两者都应该依赖其对象的抽象细节,抽象不应该依赖细节 - 4、接口隔离原则
接口细化,接口中的方法尽可能少 - 5、迪米特法则
也称"最少知识原则",一个对象,对其他对象的了解最少,调用最少。 - 6、开闭原则
对扩展开放,对修改关闭。新功能等需要通过扩展来实现。
创造类
- 单例模式
- 懒汉模式
需要时,进行初始化
- 懒汉模式
public class CTxtFile {
private CTxtFile(){}//禁止其他对象进行初始化
private static CTxtFile cTxtFile=null;
/**
* CTxtFile文件单例模式获取文件
* @return 单例的对象
*/
public static synchronized CTxtFile getInstance(){
if(null==CTxtFile.cTxtFile){
CTxtFile.cTxtFile=new CTxtFile();
}
return CTxtFile.cTxtFile;
}
}
- 饿汉模式
直接初始化
public class CTxtFile {
private CTxtFile(){}//禁止其他对象进行初始化
private static CTxtFile cTxtFile=new CTxtFile();
/**
* CTxtFile文件单例模式获取文件
* @return 单例的对象
*/
public static synchronized CTxtFile getInstance(){
return CTxtFile.cTxtFile;
}
}
- 工厂方法模式
定义1 :定义一个用于创建对象的接口,让子类去决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类。
简单理解:你是客户,需要工厂生产一些商品,需要什么类型的产品(工厂有的商品)。直接表述(createSomeThing())返回的就是这个商品(对象)。 - 抽象工厂模式
定义1 :创建一组相关的或者互相依赖的对象,提供一个借口,而无需执行它们的具体类。
简单理解:你是客户,合作方是集团公司,有很多工厂,集团公司的商务(接口)和你进行合作,你需要商品的内容可以从商务接口处调用和获取。 - 建造者模式
定义1 :将一个复杂的对象的构建和它的表示分离,使得同样的构建过程,可以创建不同的表示。
简单理解:你还是客户,不过你要求深度定制化,还是原来的商品,例如手机,这个内存要大的,那个储存要小的,芯片要订制的。同样还是手机,不同手机的配件进行组装组合,可以形成新的标识。 - 原型模式
定义1:原型实例指定创建对象的种类,并且通过拷贝这些原型创建新对象。
即深度拷贝。
在Java中,实现Java的Cloneable方法,调用clone方法。
复制对象的速度远高于new一个对象。
性能优良,直接在内存中以二进制字节码的形式进行拷贝,不执行构造函数- 普通(浅)拷贝,即赋值的是对象的引用。
行为类
- 命令模式
定义1:将请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对于请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
没有过多的时间,或者不想提供过多的接口,还想保持接口的扩展性,可以考虑此种组合方式,对请求进行封装。根据请求的具体的参数,来进行不同的操作, - 解释器模式
定义1:给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。
简单理解,就是简化版的编译原理,自行解析json,或者xml格式的文件。或者页面输入了一个符号语句,需要自行解析并进行使用。 - 责任链模式
定义1:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,并将这些对象连城一条链条,并沿着这条链传递该请求,直到有对象处理为止。
单链表结构,每个链表节点只处理自己可以处理的内容,如果不满足,则传递至下一个节点处理。 - 观察者模式,也称发布订阅模式
定义1:定义对象间一对一的依赖关系,使得每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并被更新。
简单理解就是监听,当页面上有按钮被点击时,调用的方法,就是通知。和普通页面监听的区别,发布订阅可以一人发布,多人订阅。 - 中介者模式
也叫调停者模式
定义1 :使用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示的相互作用,从而使其耦合松散。
简单理解,张三做前端,李四做后端,王五做UI设计,赵六做需求。这些人属于不同的部门,各自归属各自的部门领导管辖,项目经理这个使用的角色就是调停者,中介者。调用部门领导的接口,实际的调用四个不同部门的人员整合完成内容。(ps:这个只是举个例子) - 备忘录模式
定义1 :在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以将该对象恢复到原先保存的状态。
使用场景:
1. 需要保存和恢复数据的地方
2. 提供可回滚的操作,例如文档编辑器的Ctrl+Z退回的组合键
3. 监控一个对象的情况,例如一个数据对象的快照,用于事后排查或恢复。
4. 数据库链接的事务,就是备忘录模式。
java数据对象的全复制:
1. 备份对象
Person obj = new Person();
obj.setName("张三");
obj.setAge(20);
Map<String,Object> map = new HashMap<String,Object>();
// 获取对象的具体属性内容
BeanInfo bInfo = Introspector.getBeanInfo(obj.getClass());
// 参数数据列表
PropertyDescriptor[] pd = bInfo.getPropertyDescriptors();
for(PropertyDescriptor pro:pd){
// 获取属性名称
String name = pro.getName();
// 获取属性读取的方法
Method get = pro.getReadMethod();
// 获取属性值
Object value = get.invoke(obj,new Object[]{});
if(!name.equalsIgnoreCase("class")){
map.put(name, value);
System.out.println(name+":"+value);
}
}
其中:
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
- 还原对象
// person 定义看面的代码
Person person = new Person();
Map<String,Object> proMap = new HashMap<String,Object>();
proMap.put("name","李四");
proMap.put("age", 20);
// 获取对象的具体属性内容
BeanInfo bInfo = Introspector.getBeanInfo(Person.class);
// 参数数据列表
PropertyDescriptor[] pd = bInfo.getPropertyDescriptors();
for(PropertyDescriptor pro:pd){
// 获取属性名称
String name = pro.getName();
// 如果有这个属性
if(proMap.containsKey(name)){
Method set = pro.getWriteMethod();
set.invoke(person, new Object[]{proMap.get(name)});
}
}
System.out.println(person.getName()+":"+person.getAge());
单节点备份,在系统运行中,建议使用AOP模式进行切入。
多节点备份,建议增加上备份时间,以便还原。
备份的节点数量不能过多,以免系统包OOM异常,备份的内容及时持久化。
- 状态模式
定义1:当一个对象的内在状态改变时允许其改变行为,这个对象看起来像是改变了其类。
简单的例子,电梯,有运行,开门关门,停运状态。每个状态都会有其他状态的限制。例如,运行中不能开门。开门关门过程中不能运行。每个状态对对应的操作,都要集成,有反应或者没有反应(即限制)。 - 策略模式
定义1:定义一组算法,将每个算法封装起来,并使他们之间可以互换。
java中的Math类的方法,两元参数的,一元参数的,都是可以相互替换的。便可认为策略模式。
策略枚举,封装的方式使用枚举的方式。调用时会更加方便。 - 模板方法
定义1:定义一个操作的算法框架,而将一些步骤延迟到子类去完成,使得子类可以不改变一个算法的结构,即可重新定义该算法的某些步骤
简单理解,父子结构,父类去实现业务关系,留下具体实现业务的接口,子类继承实现具体的业务。引用和调用的是父类,实例化时,使用的是子类。
注意:一般模板方法都加上final关键字,不允许覆写,防止恶意操作。 - 访问者模式
定义1 :封装一些作用于某种数据结构中的各元素的操作。它可以在不改变数据结构的前提下定义作用于这些元素的新操作。 - 使用场景:
- 一个对象结构包含很多类对象,他们有不同的接口,而你想对这些对象实施一些依赖于其具体对象的操作,也就是说迭代器模式已经无法胜任。
- 需要对一个对象结构中的对象进行很多不同且不相关的操作,而且你想避免这些操作"污染"这些对象的操作类。
- 总结 :业务规则要求遍历多个不同的类,这也是访问者模式的出发点。
- 扩展:
- 单分派:一个操作是根据请求者的名称和接收到的参数决定的,
- 多分派:执行的操作决定于请求的种类和两个接受者的类型。
- 实际使用:可以使用过滤器或者拦截器
- 迭代器模式
基本已经用的很少了,java中我们常用List,Map已经实现了迭代器、一般是itrator()方法。
定义1 :提供一个方法访问一个容器对象中各个元素,而又不需要暴露该对象实现的具体细节
// java已经实现的迭代器的用法
List<String> list = new ArrayList<String>();
for(String str:list){
}
代码展示:设计模式-迭代器模式-代码展示
结构类
-
适配器模式
定义1:将一个借口变更为客户端所期待的另一种接口,从而使原本因为接口不匹配而无法一起工作的两个类能够在一起工作。
就是字面意思,适配器。在国内是220v交流电,在美国是110v交流电。国内外使用的适配器,都会给电脑提供稳定的电源,例如12V
示例代码:适配器模式 -
组合模式
也称合成模式,或者部分-整体模式。主要用于描述部分与整体的关系。
定义1:将对象组合成树形结构,以表示“部分-整体”的层级结构,使得用户对单个对象和组合对象的使用具有一致性。
我们最常用的省市级联的数据表,即组合模式的数据在数据库中的存放。
透明模式:叶子节点和树枝节点,为一个节点,通过标记来进行区分。
安全模式:叶子节点和树枝节点,为单独的节点实现。 -
代理模式
定义1:为其他对象提供代理,以控制该对象的访问。
透明代理:用户不用设置代理服务器地址,就可以直接访问。代理服务器对于用户来讲是透明的。
普通代理:用户需要自行设置代理服务器的IP地址,用户必须知道代理的存在。
强制代理:必须通过真实角色查找到代理角色,否则无法访问。例如你和某明星比较熟,但是你找他有些事情,他还是让你找他的经纪人。
动态代理:在现实阶段不用关心代理的是谁,而在运行阶段,才指定代理的是哪一个类。
InvocationHandler是JDK提供的动态代理接口,继承后必须实现invoke方法。通过该接口,所有的方法,都由该Handler处理。
示例源码 :代理模式展示源码 -
桥梁模式
也称桥接模式
定义1:将抽象和实现解耦,使得两者可以独立的变化。
抽象接口,抽象接口实现接口。抽象接口调用实现实现接口。
抽象接口调整,接口实现接口实例。 -
装饰模式
定义1:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
示例代码:装饰模式-示例代码 -
门面模式
也叫做外观模式,是一种比较常见的封装模式
定义1:要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个高层次的接口,使得子系统更容易使用
最简单的理解,现在互联网是提供的大量的API通过https请求参数,调用云服务厂商的服务。厂商提供的API接口类,简单可以理解为门面对象,实际实现的方法可以当成黑箱。
注意:门面对象不参与具体的业务逻辑,这样,门面对象就足够稳定。 -
享元模式
定义1:使用共享对象可以有效的支持大量的细粒度的对象。
享元模式,是池对象的重要实现方式。
参考和引用文献
注意:文中所有未提及具体位置的定义内容,均来自1