精华内容
下载资源
问答
  • Java设计模式精讲

    2015-02-04 10:44:07
    您是一个初级的 coder,可以从中领会到怎么设计一段优秀的...您是一个高级程序员,可以从中全面了解到设计模式以及 Java 的边角技术的使用;您是一个顶级的系统分析师,可以从中获得共鸣,寻找到项目公共问题的解决办法
  • java设计模式精讲 Debug 方式+内存分析,
  • 简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波 & 软件秘笈-设计模式那些事-郑阿奇 文章目录1、原型模式的定义原型-定义原型-类型2、原型模式的实现原型模式的通用类图原型...

    简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波


    原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单,使用的场景才非常地多。原型模式是创建型模式,创建型模式一般用来创建一个新的对象,然后使用这个对象完成一些对象的操作,我们通过原型模式可以快速地创建一个对象而不需要提供专门的new()操作,这无疑是一种非常有效的方式,可以快速地创建一个新的对象。

    1、原型模式的定义

    原型-定义

    定义:

    • 指原型实例指定创建对象的种类,并且通过拷贝(复制)这些原型创建新的对象。

    • 不需要知道任何创建的细节,不调用构造函数。

    Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.

    原型-类型

    类型:创建型模式-原型模式

    原型模式的最大的特点就是克隆一个现有的对象,这个克隆的结果有两种,一种是浅复制,另一种是深复制。

    比其他的简单多,那怎么用好它,这是个问题。

    2、原型模式的实现

    原型模式的通用类图

    原型模式的通用类图

    在这里插入图片描述

    实线箭头 关联关系

    三角空心实线 泛化(继承)关系

    原型模式的核心是一个clone方法,通过该方法进行对象的拷贝(复制),Java提供了一个Cloneable接口来标示这个对象是可拷贝的,为什么说是“标示”呢?

    翻开JDK的帮助看看Cloneable是一个方法都没有的,这个接口只是一个标记作用,在JVM中具有这个标记的对象才有可能被拷贝。

    那怎么才能从“有可能被拷贝”转换为“可以被拷贝”呢?方法是覆盖clone()方法,重写clone()方法。

    在clone()方法上增加了一个注解@Override,没有继承一个类为什么可以覆写呢?

    在Java中所有类的老祖宗是谁?是Object类,每个类默认都是继承了这个类,所以用覆写是非常正确的——覆写了Object类中的clone方法!在Java中原型模式是如此简单的。那到底如何实现呢?

    原型模式通用源码

    PrototypeClass.java

    /**
     * 原型模式通用代码
     */
    public class PrototypeClass  implements Cloneable{
    	
    	//覆写父类Object方法
    	@Override
    	public PrototypeClass clone(){
    		PrototypeClass prototypeClass = null;
    		try {
    			prototypeClass = (PrototypeClass)super.clone();
    		} catch (CloneNotSupportedException e) {
    			//异常处理
    		}
    		return prototypeClass;
    	}
    }
    

    实现一个接口Cloneable,然后重写clone方法,就完成了原型模式!

    3、原型模式的使用场合

    原型模式的适用场景 适合什么场景用

    • 类初始化消耗较多资源
    • new产生的一个对象需要非常繁琐得过程(数据准备、访问权限等)
    • 构造函数比较复杂
    • 循环体中生产大量对象时

    原型模式的使用场景 想用原型模式时的场景

    • 资源优化场景

    类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。

    • 性能和安全要求的场景

    通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。

    简化创建过程

    • 一个对象多个修改者的场景

    一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

    在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与Java融为一体,我们可以随手拿来使用。

    4、原型模式的应用

    原型模式-优点

    原型模式-优点

    • 性能优良

    原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。(原型模式性能比直接new一个对象性能高)

    • 逃避构造函数的约束

    这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。优点就是减少了约束,缺点也是减少了约束,使用需要在实际应用时考虑。

    原型模式性能比直接new一个对象性能高

    简化创建过程

    原型-缺点

    缺点

    • 必须配备克隆方法

    重写

    • 对克隆复杂对象或克隆出的对象进行复杂改造时,容易引入风险
    • 深拷贝、浅拷贝要运用得当

    很多坑

    原型模式的注意事项

    原型模式clone方法的有一些注意事项的。

    构造函数不会被执行

    一个实现了Cloneable并重写了clone方法的类A,有一个无参构造或有参构造B(B是构造函数),通过new关键字产生了一个对象S,再然后通过S.clone()方式产生了一个新的对象T,那么在对象拷贝时构造函数B是不会被执行的。 即对象拷贝时不会执行构造函数的。

    一小段程序来说明这个问题,如代码所示。

    代码简单的可拷贝对象 Thing.java

    /**
     * 万物
     */
    public class Thing implements Cloneable{
    	public Thing(){
    		System.out.println("构造函数被执行了...");
    	}
    	
    	@Override
    	public Thing clone(){
    		Thing thing=null;
    		try {
    			thing = (Thing)super.clone();
    		} catch (CloneNotSupportedException e) {
    			e.printStackTrace();
    		}
    		return thing;
    	}
    }
    
    

    然后我们再来写一个Client类,进行对象的拷贝,如代码所示。

    简单的场景类 Client.java

    /**
     * Client
     */
    public class Client {
    
    
    	public static void main(String[] args) {
    		//产生一个对象
    		Thing thing = new Thing();
    		
    		//拷贝一个对象
    		Thing cloneThing = thing.clone();
    
    	}
    
    }
    

    运行结果如下所示:

    构造函数被执行了...
    
    Process finished with exit code 0
    
    

    这个创建对象

    //产生一个对象 Thing thing = new Thing();

    执行了一次构造函数

    对象拷贝时构造函数确实没有被执行,这点从原理来讲也是可以讲得通的,Object类的clone方法的原理是从内存中(具体地说就是堆内存)以二进制流的方式进行拷贝,重新分配一个内存块,那构造函数没有被执行也是非常正常的了。

    浅拷贝和深拷贝

    在解释什么是浅拷贝和什么是深拷贝之前,先来看个例子,如代码所示。

    浅拷贝

    /**
     *  万物
     */
    public class Thing implements Cloneable{
    	//定义一个私有变量
    	private ArrayList<String> arrayList = new ArrayList<String>();
    
    	@Override
    	public Thing clone(){
    		Thing thing=null;
    		try {
    			thing = (Thing)super.clone();
    		} catch (CloneNotSupportedException e) {
    			e.printStackTrace();
    		}
    		return thing;
    	}
    	
    	//设置HashMap的值
    	public void setValue(String value){
    		this.arrayList.add(value);
    	}
    	
    	//取得arrayList的值
    	public ArrayList<String> getValue(){
    		return this.arrayList;
    	}
    		
    }
    

    在Thing类中增加一个私有变量arrayList,类型为ArrayList,然后通过setValue和getValue分别进行设置和取值,我们来看场景类是如何拷贝的,

    如代码清单所示。 浅拷贝测试

    /**
     * 场景类
     */
    public class Client {
    
    
    	public static void main(String[] args) {
    		//产生一个对象
    		Thing thing = new Thing();
    		//设置一个值
    		thing.setValue("张三");
    		
    		//拷贝一个对象
    		Thing cloneThing = thing.clone();
    		cloneThing.setValue("李四");
    		
    		System.out.println(thing.getValue());
    
    	}
    
    }
    
    

    猜想一下运行结果应该是什么?是仅一个“张三”吗?

    运行结果如下所示:[张三,李四]

    怎么会这样呢?怎么会有李四呢?是因为Java做了一个偷懒的拷贝动作,Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝。

    确实是非常浅,两个对象共享了一个私有变量,你改我改大家都能改,是一种非常不安全的方式,在实际项目中使用还是比较少的(当然,这也是一种“危机”环境的一种救命方式)。

    你可能会比较奇怪,为什么在Mail那个类中就可以使用String类型,而不会产生由浅拷贝带来的问题呢?内部的数组和引用对象才不拷贝,其他的原始类型比如int、long、char等都会被拷贝,但是对于String类型,Java就希望你把它认为是基本类型,它是没有clone方法的,处理机制也比较特殊,通过字符串池(stringpool)在需要的时候才在内存中创建新的字符串,读者在使用的时候就把String当做基本类使用即可。

    注意 使用原型模式时,引用的成员变量必须满足两个条件才不会被拷贝:一是类的成员变量,而不是方法内变量;二是必须是一个可变的引用对象,而不是一个原始类型或不可变对象。浅拷贝是有风险的,那怎么才能深入地拷贝呢?我们修改一下程序就可以深拷贝,如代码所示。

    代码 深拷贝

    /**
     *  万物
     */
    public class Thing implements Cloneable{
    	//定义一个私有变量
    	private ArrayList<String> arrayList = new ArrayList<String>();
    
    	@Override
    	public Thing clone(){
    		Thing thing=null;
    		try {
    			thing = (Thing)super.clone();
    			thing.arrayList =(ArrayList<String>)this.arrayList.clone();//深拷贝
    		} catch (CloneNotSupportedException e) {
    			e.printStackTrace();
    		}
    		return thing;
    	}
    	
    	//设置HashMap的值
    	public void setValue(String value){
    		this.arrayList.add(value);
    	}
    	
    	//取得arrayList的值
    	public ArrayList<String> getValue(){
    		return this.arrayList;
    	}
    		
    }
    
    
    

    仅仅增加了thing.arrayList =(ArrayList<String>)this.arrayList.clone();//深拷贝,对私有的类变量进行独立的拷贝。Client类没有任何改变,

    运行结果如下所示:[张三]该方法就实现了完全的拷贝,两个对象之间没有任何的瓜葛了,你修改你的,我修改我的,不相互影响,这种拷贝就叫做深拷贝。深拷贝还有一种实现方式就是通过自己写二进制流来操作对象,然后实现对象的深拷贝,有时间实现一下。

    注意: 深拷贝和浅拷贝建议不要混合使用,特别是在涉及类的继承时,父类有多个引用的情况就非常复杂,建议的方案是深拷贝和浅拷贝分开实现。

    clone与final两个冤家

    对象的clone与对象内的final关键字是有冲突的,我们举例来说明这个问题,如代码所示。

    代码 增加final关键字的拷贝

    **
     * 万物
     */
    public class Thing implements Cloneable{
    	//定义一个私有变量
    	private final ArrayList<String> arrayList = new ArrayList<String>();
    
    	@Override
    	public Thing clone(){
    		Thing thing=null;
    		try {
    			thing = (Thing)super.clone();	
    			this.arrayList = (ArrayList<String>)this.arrayList.clone();
    		} catch (CloneNotSupportedException e) {
    			e.printStackTrace();
    		}
    		return thing;
    	}
    	
    	//设置HashMap的值
    	public void setValue(String value){
    		this.arrayList.add(value);
    	}
    	
    	//取得arrayList的值
    	public ArrayList<String> getValue(){
    		return this.arrayList;
    	}
    		
    }
    

    粗体部分仅仅增加了一个final关键字,然后编译器就报斜体部分错误,正常呀,final类型你还想重赋值呀!你要实现深拷贝的梦想在final关键字的威胁下破灭了,路总是有的,我们来想想怎么修改这个方法:删除掉final关键字,这是最便捷、安全、快速的方式。你要使用clone方法,在类的成员变量上就不要增加final关键字。注意 要使用clone方法,类的成员变量上不要增加final关键字。这个代码去掉final就可以运行了

    原型-扩展

    扩展

    • 深克隆
    • 浅克隆

    Coding

    源码解析

    克隆

    扩展:Java SDK中的原型模式其实,在上面的例子中,我们就已经在使用JDK中的原型设计模式了。Object类是所有类的超类,子类可以重载Object类的clone方法克隆对象,但是必须记得一定要实现Cloneable接口才行,因为只有实现该接口的对象才能被复制。Object类的原型模式如图所示。

    在这里插入图片描述

    5、设计原则

    原型模式的核心是一个clone方法,通过这个方法进行对象的复制,在Java中,提供了一个Cloneable接口来标示这个对象是可复制的,为什么说是“标示”呢?查看Cloneable类源码,会发现,Cloneable接口中一个方法都没有,这个接口的作用就是一个标示,只有实现该接口的对象才有可能被复制!到这里你可能又要问了,那又如何从“有可能被复制”变为“可以被复制”呢?方法就是覆盖超类的clone()方法!

    原型设计模式的原则还是在解耦上。我们在类的交互中可以不把类名塞到源文件中,那样类将耦合在一起,达不到类复用的作用。当然,必须紧密结合在一起的类是应当将类名写到一起的,以增加系统的高内聚性,而那些应该独立成组件的类,则应当被分离出来。

    6、最佳实践

    原型模式先产生出一个包含大量共有信息的类,然后可以拷贝出副本,修正细节信息,建立了一个完整的个性对象。原型模式也就是由一个正本可以创建多个副本的概念。可以这样理解:一个对象的产生可以不由零起步,直接从一个已经具备一定雏形的对象克隆,然后再修改为生产需要的对象。

    7、总结

    1.原型模式

    用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

    2.注意事项

    (1)克隆对象时,原始对象的构造方法不被执行。

    (2)浅复制:浅复制只是复制本对象的原始数据类型,如int、float、String等,对于数组和对象引用等是不会复制的。因此,浅复制是有风险的。

    (3)深复制:不但对原始数据类型做复制,对于对象中的数组和对象引用也做复制的行为,从而达到将对象完全复制的效果。

    3.设计原则

    (1)考虑产生对象的复杂度和类复用;

    (2)结合系统结构考虑使用浅复制还是深复制。

    4.使用场合

    (1)产生对象过程比较复杂,初始化需要许多资源时;

    (2)希望框架原型和产生对象分开时;

    (3)同一个对象可能会供其他调用者同时调用访问时。

    原型模式(Proxy Pattern)

    定义:Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    原型模式的通用类图如下图:

    在这里插入图片描述

    原型模式的核心是一个clone方法,通过该方法进行对象的拷贝,Java提供了一个Cloneable接口来标示这个对象是可拷贝的,为什么说是“标示”呢?翻开JDK的帮助看看Cloneable是一个方法都没有的,这个接口只是一个标记作用,在JVM中具有这个标记的对象才有可能被拷贝,那怎么才能从“有可能被拷贝”转换为“可以被拷贝”呢?方法是覆盖clone()方法。实现一个接口,然后重写clone方法,就完成了原型模式!

    原型模式的应用

    1.原型模式的优点

    • 性能优良。原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好的体现其优点。
    • 逃避构造函数的约束。这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的(见“原型模式的注意事项”),优点就是减少了约束,缺点也是减少了约束,双刃剑,需要大家在实际应用时考虑。

    2.原型模式的使用场景

    • 资源优化场景。类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
    • 性能和安全要求的场景。通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
    • 一个对象多个修改者的场景。一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

    在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过clone的方法创建一个对象,然后由工厂方法提供给调用者。原型模式已经与Java融为浑然一体,大家可以随手拿来使用。

    原型模式的注意事项

    • 构造函数不会被执行。
    • 浅拷贝和深拷贝。Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝,确实是非常浅,两个对象共享了一个私有变量,你改我改大家都能改,是一种非常不安全的方式,在实际项目中使用还是比较少的(当然,这是也是一种“危机”环境的一种救命方式)。内部的数组和引用对象才不拷贝,其他的原始类型比如int,long,String(Java就希望你把String认为是基本类型,String是没有clone方法的)等都会被拷贝的。(注意:使用clone方法拷贝时,满足两个条件的对象才不会被拷贝:一是类的成员变量,而不是方法内的变量;二是必须是一个对象,而不是一个原始类型)
    • clone与final两对冤家。对象的clone与对象内的final关键字是有冲突的。要使用clone方法,类的成员变量上不要增加final关键字。
    展开全文
  • java设计模式精讲 /Debug 方式/内存分析(包含其他缺失的16章)
  • 简单记录 - 慕课网 - Java设计模式精讲 Debug方式+内存分析 文章目录第2章 UML急速入门2-1、UML简单入门UML定义UML特点UML 2.2分类UML类图理解泛化、实现理解依赖、关联理解聚合、组合UML时序图2-2、UML类 图讲解2-3...

    简单记录 - 慕课网 - Java设计模式精讲 Debug方式+内存分析

    第2章 UML急速入门

    主要讲解UML基础、UML类图、UML类关系、UML时序图、UML类关系记忆技巧等,让大家急速入门UML,从而为后面设计模式的学习做好准备。

    • 2-1 本章导航
    • 2-2 UML类图讲解
    • 2-3 UML类图讲解-自上而下
    • 2-4 UML类图讲解-对比讲解联想记忆

    2-1、UML简单入门

    UML类图及时序图入门

    定义 特点 分类

    类图 时序图 记忆技巧

    UML角度 理解 设计模式

    UML定义

    UML定义

    • 统一建模语言(英文:Unified Modeling Language,缩写UML)
    • 非专利的第三代建模和规约语言

    UML特点

    UML特点

    • UML是一种开发的方法

    • 用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品的开发方法。

      制品 软件开发过程中 产物 模型 各种流程图 源代码 测试用例 等等 可视化 描述

    • UML展现了一系列最佳工程实践

      这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效 通过UML对系统更深理解

    UML 2.2分类

    UML2.2中一共定义了14种图示,分类如下:

    • 结构式图形:强调的是系统式的建模
    • 行为式图形:强调系统模型中触发的事件
    • 交互式图形:属于行为式图形子集合,强调系统模型中资料流程。

    结构式图形

    • 静态图(类图、对象图、包图)
    • 实现图(组件图、部署图)
    • 剖面图
    • 复合结构图

    行为式图形

    • 活动图
    • 状态图
    • 用例图

    交互式图形

    • 通信图
    • 交互概述图(UML2.0)
    • 时序图(UML2.0)
    • 时间图(UML2.0)

    UML类图

    • Class Diagram:用于表示类、接口、实例等之间相互的静态关系
    • 虽然名字叫类图,但类图中并不只是类 包括权限、属性、方法等等

    理解泛化、实现

    泛化关系 继承关系 记忆技巧

    • UML箭头方向:从子类指向父类

    • 提示:可能会认为子类是以父类为基础的,箭头应从父类指向子类

      从来没有这么想过

      记忆技巧-箭头方向

      • 定义子类时需要通过extends关键字指向父类
      • 子类一定是知道父类定义的,但父类并不知道子类的定义
      • 只有知道对方信息时才能指向对方

      UML 所以箭头方法从子类指向父类

    实线-继承 | 虚线-实现

    在这里插入图片描述

    实现关系

    • 被一个类实现了 ,A类实现B接口 实现关系

    • 三角空心虚线

    实现关系、继承关系

    实线-继承 | 虚线-实现

    • 空心三角箭头:继承或实现

    • 实线-继承 ,is a 关系,扩展目的,不虚,很结实的。

    • 虚线-实现,虚线代表“虚”无实体。实现接口 实现接口方法

    理解依赖、关联

    实线 -关联 | 虚线-依赖

    关联关系 实线

    在这里插入图片描述

    依赖关系

    在这里插入图片描述

    实线 -关联 | 虚线-依赖

    依赖关系 虚线

    • 虚线-依赖关系:临时用一下,若即若离,虚无缥缈,若有若无

      调用的时候才会用一下 虚线 依赖关系

    • 表示一种使用关系,一个类需要借助另一个类来实现功能

    • 一般是一个类使用另一个类做为参数使用,或作为返回值 参数 返回值

    关系关系 实线

    • 实线-关联关系:关系稳定,实打实的关系,铁哥们。
    • 表示一个类对象和另一个类对象有关联
    • 通过是一个类中有另一个类对象做为属性 属性 一个成员变量

    理解聚合、组合

    空心菱形-聚合 | 实心菱形-组合

    • 菱形就是一个盛东西的器皿(例如盘子)

    • 聚合:代表空器皿里可以放很多相同的东西,聚在一起(箭头方向所指的类 个体

    • 组合:代表满器皿里已经有实体结构的存在,生死与共 强关系

    整体与部分 可以离聚合 不可以离组合

    在这里插入图片描述

    组合关系

    鸟和翅膀 人和头 强关系 相同的生命周期 你死我也死

    在这里插入图片描述

    数字?

    空心菱形 聚合关系 记忆技巧

    • 整体和局部的关系,两者有着独立的生命周期,是has a的关系

    • 弱关系

      大雁群 has a 大雁

    • 消极的词:弱 - 空 空心菱形

    实心菱形 组合关系 记忆技巧

    • 整体与局部的关系,和聚合的关系相比,关系更加强烈

      两者有相同的生命周期,contains-a的关系 包含

    • 强关系

    • 积极的词:强 - 满 实心菱形

    在这里插入图片描述

    常见数字表达及含义

    一个鸟 两个翅膀

    UML时序图

    在这里插入图片描述

    生命线 上到下 时间的流逝

    方法调用

    消息

    在这里插入图片描述

    类图 时序图 用例图 重要

    时序图 调用关系

    2-2、UML类 图讲解

    类的表示

    类名 抽象类 斜体表示 接口 <>

    属性 行为

    public + private - protected #

    什么都不加 or ~ 是表示 default

    + max

    - min private

    # protected

    在这里插入图片描述

    横线 static 属性

    横线 static 静态方法

    斜体 抽象方法 有抽象方法 是抽象类 要斜体来表示一下咯所以上面那个图错了

    是抽象类 有抽象方法

    有抽象方法的是抽象类 抽象类要斜体来表示一下

    在这里插入图片描述

    记住这个类图

    类图表示 要 准确 避免产生歧义

    2-3、UML类图讲解 自上而下

    大话设计模式的图 UML图

    在这里插入图片描述

    一起来学习吧

    依赖关系

    虚线箭头 箭头方向 指向被依赖的对象

    在这里插入图片描述

    • 表示一种使用关系,一个类需要借助另一个类来实现功能
    • 一般是一个类使用另一个类做为参数使用,或作为返回值 参数 返回值

    鸟是一种动物

    在这里插入图片描述
    父类 子类 鸟继承动物 箭头方向:子类指向父类

    • UML箭头方向:从子类指向父类

    • 提示:可能会认为子类是以父类为基础的,箭头应从父类指向子类

      从来没有这么想过

      记忆技巧-箭头方向

      • 定义子类时需要通过extends关键字指向父类
      • 子类一定是知道父类定义的,但父类并不知道子类的定义
      • 只有知道对方信息时才能指向对方

      UML 所以箭头方法从子类指向父类

    实线-继承 | 虚线-实现

    • 空心三角箭头:继承或实现

    • 实线-继承 ,is a 关系,扩展目的,不虚,很结实的。

    • 虚线-实现,虚线代表“虚”无实体。实现接口 实现接口方法

    关联关系

    在这里插入图片描述

    关联关系 实线

    • 实线-关联关系:关系稳定,实打实的关系,铁哥们。
    • 表示一个类对象和另一个类对象有关联
    • 通过是一个类中有另一个类对象做为属性 属性 一个成员变量

    有一个类对象的属性

    聚合关系

    在这里插入图片描述

    空心菱形 聚合关系 记忆技巧

    • 整体和局部的关系,两者有着独立的生命周期,是has a的关系

    • 弱关系

      大雁群 has a 大雁

    • 消极的词:弱 - 空 空心菱形

    整体 大雁群 局部、部分 大雁

    空心菱形 菱形指向很多大雁也就是大雁群 箭头指向大雁

    实现关系 空心三角虚线 表示实现关系

    在这里插入图片描述

    空心三角虚线 大雁实现了飞翔这个接口

    棒棒糖表示法 接口表示 实现关系
    在这里插入图片描述

    在这里插入图片描述

    2-4、UML类图讲解 - 对比讲解联想记忆

    依赖关系 虚线箭头 参数、返回值 使用的时候才会关注

    关联关系 实线箭头 实打实的关系 ,一般用了一个类对象作为另一个类的属性

    聚合关系 空心菱形 菱形在整体 箭头在部分 聚在一起 独立的生命周期 弱关系

    组合关系 实心菱形 强关系 人与头 人挂了 头也没生命力了

    继承关系 三角空心实线 类和类之间的关系 继承 子类指向父类

    实现关系 三角空心虚线 虚 实现 指向要被实现的接口

    看图 项目代码 看看UML图 快速理解项目

    总结

    • 定义

    • 特点

    • 分类

    • 类图

    • 时序图

    • 记忆技巧 理解 多用

    展开全文
  • 图解Java设计模式之设计模式面试题1.1 Java设计模式内容介绍1.1.1 先看几个经典的面试题1.1.2 设计模式的重要性1.1 Java设计模式内容介绍1.1.1 先看几个经典的面试题原型设计模式问题 :1)有请使用UML类图画出原型...

    图解Java设计模式之设计模式面试题

      • 1.1 Java设计模式内容介绍
        • 1.1.1 先看几个经典的面试题
        • 1.1.2 设计模式的重要性

    1.1 Java设计模式内容介绍

    1.1.1 先看几个经典的面试题

    • 原型设计模式问题 :
      1)有请使用UML类图画出原型模式核心角色
      2)原型设计模式的深拷贝和浅拷贝是什么。并写出深拷贝的两种方式的源码(重写clone方法实现深拷贝、使用序列化来实现深拷贝)
      3)在Spring框架中哪里使用到原型模式,并对源码进行分析
      beans.xml

    <bean id="id01" class="com.demo.spring.bean.Monster" scope="prototype" />

    4)Spring中原型bean的创建,就是原型模式的应用
    5)代码分析 + Debug源码

    • 设计模式的七大原则 :要求 :
      1)七大设计原则核心思想
      2)能够以类图的说明设计原则
      3)在项目实际开发中,你在哪里使用到来ocp原则设计模式常用的七大原则有 :
      1)单一职责原则
      2)接口隔离原则
      3)依赖倒转原则
      4)里氏替换原则
      5)开闭原则ocp
      6)迪米特法则7)合成复用原则

    15242e251f084a19e0b3fda58dd96400.png
    • 金融借贷平台项目 : 借贷平台的订单,有审核-发布-抢单等等步骤,随着操作的不同,会改变订单的状态,项目中的这个模块实现就会使用到状态模式,请你使用状态模式进行设计,并完成实际代码问题分析 :
      这类代码难以应对变化,在添加一种状态时,我们需要手动添加if/else,在添加一种功能时,要对所有的状态进行判断。因此代码会变得越来越臃肿,并且一旦没有处理某个状态,便会发生极其严重的BUG,难以维护。

    7f5a8eda7ab0766e13ca7496dc0b55f2.png

    31053d92a7db61cac6931cf5a2402bd3.png
    • 解释器设计模式
      1)介绍解释器设计模式是什么?
      2)画出解释器设计模式的UML类图,分析设计模式中的各个角色是什么?
      3)请说明Spring的框架中,哪里使用到来解释器设计模式,并做源码级别的分析

    4cfc51503f4ce04466d379d07c4990b8.png


    解释器模式在Spring框架应用的源码剖析
    1)Spring框架中SpelExpressionParser就使用到解释器模式
    2)代码分析 + Debug源码 + 模式角色分析说明

    019a0b8d9e27775810312c5897ac3bfe.png

    9aecac57fdc7c8598ce9c6f9f1679b66.png
    • 单例设计模式一共有几种实现方式?请分别用代码实现,并说明各个实现方式的优点和缺点?
      单例设计模式一共有8种写法,后面会依次讲到
      1)饿汉式 两种
      2)懒汉式 三种
      3)双重检查
      4)静态内部类
      5)枚举

    73eebc7abc3e0cc94ca2972f1b58c8e5.png

    1.1.2 设计模式的重要性

    1)软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是埃里希·伽玛等人在1990年代从建筑设计领域引入到计算机科学的
    2)大厦 VS 简易房

    5d0af88ac69781c215e4511b3570b3da.png


    3)拿实际工作经历来说,当一个项目开发完后,如果客户提出增新功能,怎么办?(可扩展性,使用设计模式,软件具有很好的扩展性)
    4)如果项目开发完后,原来程序员离职,你接手维护该项目怎么办?(维护性【可读性、规范性】)
    5)目前一线IT公司,都会问在实际项目中使用过什么设计模型,怎样使用的,解决来什么问题。
    6)设计模式在软件中哪里?面向对象(oo) =》功能模块【设计模式 + 算法(数据结果)】 =》框架【使用到多种设计模式】=》架构【服务器集群】

    展开全文
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 适配器模式讲解 定义:将一个类的接口转换成客户期望的另一个...

    声明:

    本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。

    本博客已标明出处,如有侵权请告知,马上删除。

    1. 适配器模式讲解

    • 定义:将一个类的接口转换成客户期望的另一个接口
    • 使原本接口不兼容的类可以一起工作
    • 类型:结构型
    • 适用场景
      • 已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
      • 不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案
    • 优点
      • 能提高类的透明性和复用,现有的类复用但不需要改变
      • 目标类和适配器类解耦,提高程序扩展性
      • 符合开闭原则
    • 缺点
      • 适配器编写过程需要全面考虑,可能会增加系统的复杂性
      • 增加系统代码可读的难度
    • 拓展
      • 对象适配器:符合合成复用原则,使用委托机制
      • 类适配器:通过类继承来实现
    • 相关设计模式
      • 适配器模式和外观模式
        • 适配器模式和外观模式都是对现有的类的封装
        • 适配器模式是复用一个原有的接口,外观模式定义了新的接口
        • 适配器模式是使两个原有的接口协同工作,外观模式则是在现有的系统中提供一个更为方便的访问入口

    2. 适配器模式 Coding

    适配器模式分为对象适配器和类适配器,他们的区别在于对象适配器通过组合实现,类适配器通过继承实现,下面分别进行演示。

    类适配器

    1. 创建一个被适配类

      public class Adaptee {
          public void adapteeRequest() {
              System.out.println("被适配者的方法");
          }
      }
      
    2. 创建目标方法的接口

      public interface Target {
          void request();
      }
      
    3. 创建接口实现类

      public class ConcreteTarget implements Target {
          @Override
          public void request() {
              System.out.println("ConcreteTarget目标方法");
          }
      }
      
    4. 创建适配器类,继承被适配类,实现目标方法接口

      public class Adapter extends Adaptee implements Target {
          @Override
          public void request() {
              super.adapteeRequest();
          }
      }
      
    5. 测试类

      public class Test {
          public static void main(String[] args) {
              Target target = new ConcreteTarget();
              target.request();
      
              // 通过适配器实现
              Target adapterTarget = new Adapter();
              adapterTarget.request();
          }
      }
      

      运行结果:

      ConcreteTarget目标方法
      被适配者的方法
      

      分析:当我们调用适配器类的目标方法时,实际调用的是被适配类中的方法。

    现在类图如下所示:
    在这里插入图片描述

    对象适配器

    还是上面的业务场景,使用对象适配器只需要修改适配器类。

    适配器类不再继承被适配类,而是将被适配类作为属性组合到适配器中,然后通过对象来调用被适配类里面的方法

    public class Adapter implements Target {
        private Adaptee adaptee = new Adaptee();
    
        @Override
        public void request() {
            adaptee.adapteeRequest();
        }
    }
    

    现在类图如下所示:

    在这里插入图片描述

    下面我们再类引入一个生活场景:手机充电器的适配器,将 220V 的交流电转换成 5V 的直流电。

    1. 创建被适配的类,220V 的交流电类

      public class AC220 {
          public int outputAC220V() {
              int output = 220;
              System.out.println("输出220V的交流电"+output+"V");
              return output;
          }
      }
      
    2. 创建目标方法的接口,5V 的直流电类

      public interface DC5 {
          int outputDC5V();
      }
      
    3. 创建适配器类

      public class PowerAdapter implements DC5 {
      
          private AC220 ac220 = new AC220();
      
          @Override
          public int outputDC5V() {
              int adapterInput = ac220.outputAC220V();
              /** 变压器 */
              int adapterOutput = adapterInput / 44;
              System.out.println("通过PowerAdapter电源适配器输入AC"+adapterInput+"V"+"输出DC:"+adapterOutput+"V");
              return adapterOutput;
          }
      }
      
    4. 测试类

      public class Test {
          public static void main(String[]args){
              DC5 dc5 = new PowerAdapter();
              dc5.outputDC5V();
          }
      }
      

      运行结果:

      输出220V的交流电220V
      通过PowerAdapter电源适配器输入AC220V输出DC:5V
      
    展开全文
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 代理模式讲解 定义:为其他对象提供一种代理,以控制对这个...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 策略模式讲解 定义:定义了算法家族,分别封装起来,让它们...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 观察者模式讲解 定义:定义了对象之间的一对多依赖,让多个...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 简单工厂讲解 定义:由一个工厂对象决定创建出哪一种产品类的...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 装饰者模式讲解 定义:在不改变原有对象的基础之上,将功能...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 抽象工厂讲解 定义:抽象工厂模式提供一个创建一系列相关或...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 工厂方法讲解 定义:定义一个创建对象的接口,但让实现这个...
  • java设计模式精讲 第2章 UML急速入门2-1本章导航UML的定义UML的特点UML2.2的分类UML类图记忆技巧UML时序图2-2UML类图讲解2-3 详细案例讲解依赖关系:继承的关系组合关系关联关系聚合关系实现接口实现接口2 - 棒棒糖...
  • Java设计模式精讲—慕课网—课程笔记3 8 单例模式讲解+Coding+源码解析 8.1 单例模式讲解 8.2 单例设计模式——懒汉式及多线程Debug实战 8.3 单例设计模式——DoubleCheck双重检查实战及原理解析 8.4 单例设计模式...
  • Java设计模式精讲 Debug方式+内存分析[完整版] 系统学习设计原则,设计模式,锤炼编码内功,赢取高薪 Offer 下载地址: https://download.csdn.net/download/weixin_38779390/12542938(资源正在审核)
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 七大原则 开闭原则 依赖倒置原则 单一职责原则 接口隔离原则 ...
  • f __set__(self, instance, value):instance.__dict__[self.name] = value# Descriptor for enforcing typesclass Typed(Descriptor):expected_type = type(None)def __set__(self, instance, value):if not isinsta...
  • @java设计模式精讲 Debug 方式+内存分析-第2章本章导航UML的定义UML的特点UML2.2的分类UML类图记忆技巧UML时序图UML类图讲解 本章导航 UML的定义 UML的特点 UML2.2的分类 结构式图形 行为式...
  • 前言这篇分享作为一个系列分享的第一篇,主要和大家一起学习一下java设计模式方面的基础,我们现在的安卓开发主要还是基于java语言,所以掌握java本身的基础也是非常重要的。在j2ee、web和安卓其他一些java程序开发...
  • Java设计模式精讲—慕课网—课程笔记23 软件设计七大原则3.1 本章导航3.2 开闭原则+coding3.4 依赖倒置原则+coding3.5 单一职责原则+coding3.6 接口隔离原则+coding3.7 迪米特原则+coding3.8 里氏替换原则+coding3.9...
  • Java设计模式精讲—课程笔记7 15 桥接模式讲解+Coding+源码解析 15.1 桥接模式讲解 15.2 桥接模式Coding 15.3 桥接模式源码解析(jdk) 16 代理模式讲解+Coding+源码解析 16.1 代理模式讲解 16.2 代理模式Coding-...
  • Java设计模式精讲—慕课网—课程笔记5 9 原型模式讲解+Coding+源码解析 9.1 原型模式讲解 9.2 原型模式coding 9.3 原型模式coding—克隆破坏单例 9.4 原型模式源码解析 10 外观模式讲解+Coding+源码解析 10.1 外观...
  • Java设计模式精讲—慕课网—课程笔记6 12 适配器模式讲解+Coding+源码解析 12.1 适配器模式讲解 12.2 适配器模式coding 12.3 适配器模式源码解析(jdk+spring+springjpa+spingmvc) 13 享元模式讲解+Coding+源码解析...
  • Java设计模式精讲—课程笔记818 迭代器模式讲解+源码解析18.1 迭代器模式讲解18.2 迭代器模式代码解析18.3 迭代器模式源码解析(jdk+mybatis)19 策略模式讲解+Coding+源码解析19.1 策略模式讲解19.2 策略模式coding...
  • Java设计模式精讲—课程笔记921 观察者模式讲解+Coding+源码解析21.1 观察者模式讲解21.2 观察者模式coding21.3 观察者模式源码解析-jdk-guava22 备忘录模式讲解+Coding+源码解析22.1 备忘录模式讲解22.2 备忘录模式...
  • Java设计模式精讲—课程笔记1025 责任链模式讲解+Coding+源码解析25.1 责任链模式讲解25.2 责任链模式coding25.3 责任链模式源码-servlet26 访问者模式讲解+源码解析26.1 访问者模式讲解26.2 访问者模式coding26.3 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 815
精华内容 326
关键字:

java设计模式精讲

java 订阅