精华内容
下载资源
问答
  • java设计模式精讲 Debug 方式+内存分析,
  • Java设计模式精讲

    2015-02-04 10:44:07
    您是一个初级的 coder,可以从中领会到怎么设计一段优秀的...您是一个高级程序员,可以从中全面了解到设计模式以及 Java 的边角技术的使用;您是一个顶级的系统分析师,可以从中获得共鸣,寻找到项目公共问题的解决办法
  • java设计模式精讲 /Debug 方式/内存分析(包含其他缺失的16章)
  • Java设计模式精讲 Debug方式+内存分析[完整版] 系统学习设计原则,设计模式,锤炼编码内功,赢取高薪 Offer 下载地址: https://download.csdn.net/download/weixin_38779390/12542938(资源正在审核)

    Java设计模式精讲 Debug方式+内存分析[完整版]

    系统学习设计原则,设计模式,锤炼编码内功,赢取高薪 Offer

    下载地址: https://download.csdn.net/download/weixin_38779390/12542938(资源正在审核)

    在这里插入图片描述

    展开全文
  • 原型模式9-1 原型模式讲解9-2 原型模式coding9-3 原型模式coding-克隆破坏单例9-4 原型模式源码解析 9-1 原型模式讲解 9-2 原型模式coding 有一个Mail类: public class Mail { private String name; ...

    9-1 原型模式讲解

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    9-2 原型模式coding

    有一个Mail类:

    public class Mail {
        private String name;
        private String emailAddress;
        private String content;
    
        public Mail() {
            System.out.println("Mail Class Constructor");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getEmailAddress() {
            return emailAddress;
        }
    
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        @Override
        public String toString() {
            return "Mail{" +
                    "name='" + name + '\'' +
                    ", emailAddress='" + emailAddress + '\'' +
                    ", content='" + content + '\'' +
                    '}';
        }
    }
    

    还有一个发送邮件的类:
    注:这里面的MessageFormat.format方法是用来拼接字符串的;

    public class MailUtil {
        public static void sendMail(Mail mail) {
            String outputContent = "向{0}同学,邮件地址:{1},邮件内容:{2}发送邮件成功!";
            System.out.println(MessageFormat.format(outputContent, mail.getName(), mail.getEmailAddress(), mail.getContent()));
        }
    
        public static void saveOriginMailRecord(Mail mail) {
            System.out.println("存储OriginMail记录,OriginMail:"+mail.getContent());
        }
    }
    

    测试:

    public class Test {
        public static void main(String[]args){
            Mail mail = new Mail();
            mail.setContent("初始化的模板");
            for (int i = 0; i < 10; i++) {
                mail.setName("姓名"+i);
                mail.setEmailAddress("姓名" + i + "@126.com");
                mail.setContent("恭喜您,此次活动中奖了!");
                MailUtil.sendMail(mail);
            }
            MailUtil.saveOriginMailRecord(mail);
        }
    }
    

    测试结果:

    Mail Class Constructor
    向姓名0同学,邮件地址:姓名0@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名1同学,邮件地址:姓名1@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名2同学,邮件地址:姓名2@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名3同学,邮件地址:姓名3@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名4同学,邮件地址:姓名4@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名5同学,邮件地址:姓名5@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名6同学,邮件地址:姓名6@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名7同学,邮件地址:姓名7@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名8同学,邮件地址:姓名8@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    向姓名9同学,邮件地址:姓名9@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    存储OriginMail记录,OriginMail:恭喜您,此次活动中奖了!


    现在,我们来用原型模式来写:
    我们让Mail拥有克隆的功能,实现Cloneable接口:

    public class Mail implements Cloneable{
        private String name;
        private String emailAddress;
        private String content;
    
        public Mail() {
            System.out.println("Mail Class Constructor");
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getEmailAddress() {
            return emailAddress;
        }
    
        public void setEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        @Override
        public String toString() {
            return "Mail{" +
                    "name='" + name + '\'' +
                    ", emailAddress='" + emailAddress + '\'' +
                    ", content='" + content + '\'' +
                    '}';
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            System.out.println("Clone mail object");
            return super.clone();
        }
    }
    

    测试:

    public class Test {
        public static void main(String[]args) throws CloneNotSupportedException {
            Mail mail = new Mail();
            mail.setContent("初始化的模板");
            for (int i = 0; i < 10; i++) {
                /** 使用克隆出来的Mail */
                Mail mailTemp = (Mail) mail.clone();
                mailTemp.setName("姓名"+i);
                mailTemp.setEmailAddress("姓名" + i + "@126.com");
                mailTemp.setContent("恭喜您,此次活动中奖了!");
                MailUtil.sendMail(mailTemp);
            }
            MailUtil.saveOriginMailRecord(mail);
        }
    }
    

    测试结果:

    Mail Class Constructor
    Clone mail object
    向姓名0同学,邮件地址:姓名0@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名1同学,邮件地址:姓名1@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名2同学,邮件地址:姓名2@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名3同学,邮件地址:姓名3@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名4同学,邮件地址:姓名4@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名5同学,邮件地址:姓名5@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名6同学,邮件地址:姓名6@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名7同学,邮件地址:姓名7@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名8同学,邮件地址:姓名8@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Clone mail object
    向姓名9同学,邮件地址:姓名9@126.com,邮件内容:恭喜您,此次活动中奖了!发送邮件成功!
    Disconnected from the target VM, address: ‘127.0.0.1:61704’, transport: ‘socket’
    存储OriginMail记录,OriginMail:初始化的模板


    在原型模式中,还有一种常见的使用方法:通过抽象类来实现原型模式
    父类实现了克隆的接口:

    public abstract class A implements Cloneable {
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    子类也具有克隆的方法:

    public class B extends A {
        public static void main(String[]args) throws CloneNotSupportedException {
            B b = new B();
            b.clone();
        }
    }
    

    在实际的开发当中,直接让目标类实现Cloneable接口的方式用的比较多;


    我们来说说克隆:深拷贝和浅拷贝
    有一个Pig类:

    public class Pig implements Cloneable{
        private String name;
        private Date birthday;
    
        public Pig(String name, Date birthday) {
            this.name = name;
            this.birthday = birthday;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    
        @Override
        public String toString() {
            return "Pig{" +
                    "name='" + name + '\'' +
                    ", birthday=" + birthday +
                    '}'+super.toString();
        }
    }
    

    测试:

    public class Test {
        public static void main(String[]args) throws CloneNotSupportedException {
            Date birthday = new Date(0L);
            Pig pig1 = new Pig("佩奇", birthday);
            Pig pig2 = (Pig) pig1.clone();
            System.out.println(pig1);
            System.out.println(pig2);
        }
    }
    

    测试结果:这是两个不同的对象

    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@27973e9b
    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@312b1dae


    现在,我们来修改pig1的生日:
    我们预期是只修改pig1的时间:

    public class Test {
        public static void main(String[]args) throws CloneNotSupportedException {
            Date birthday = new Date(0L);
            Pig pig1 = new Pig("佩奇", birthday);
            Pig pig2 = (Pig) pig1.clone();
            System.out.println(pig1);
            System.out.println(pig2);
    
            pig1.getBirthday().setTime(666666666L);
            System.out.println(pig1);
            System.out.println(pig2);
        }
    }
    

    但是实际的结果是把两个对象的时间都进行了修改,这个就是和我们的预期就是不一样了:

    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@27973e9b
    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@312b1dae
    Pig{name=‘佩奇’, birthday=Fri Jan 09 01:11:06 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@27973e9b
    Pig{name=‘佩奇’, birthday=Fri Jan 09 01:11:06 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@312b1dae


    在这里插入图片描述
    这种默认的克隆方式就是一个浅克隆的方式;


    现在,我们来实现一个深克隆:
    在Pig的这个类里面实现这个方法:

        @Override
        protected Object clone() throws CloneNotSupportedException {
            Pig pig = (Pig) super.clone();
            /** 深克隆 */
            pig.birthday = (Date) pig.birthday.clone();
            return pig;
        }
    

    Pig的这个类如下:

    public class Pig implements Cloneable{
        private String name;
        private Date birthday;
    
        public Pig(String name, Date birthday) {
            this.name = name;
            this.birthday = birthday;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Date getBirthday() {
            return birthday;
        }
    
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            Pig pig = (Pig) super.clone();
            /** 深克隆 */
            pig.birthday = (Date) pig.birthday.clone();
            return pig;
        }
    
        @Override
        public String toString() {
            return "Pig{" +
                    "name='" + name + '\'' +
                    ", birthday=" + birthday +
                    '}'+super.toString();
        }
    }
    

    这个时候,日期对象就不是同一个对象了:
    在这里插入图片描述
    这个时候,输出就符合了我们的预期了:只修改了Pig1

    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@34ce8af7
    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@b684286
    Pig{name=‘佩奇’, birthday=Fri Jan 09 01:11:06 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@34ce8af7
    Pig{name=‘佩奇’, birthday=Thu Jan 01 08:00:00 CST 1970}com.ldc.design.pattern.creational.prototype.clone.Pig@b684286


    总结:对于引用类型的变量,我们一定是注意是否要深克隆它,对于引用类型,我们还是建议克隆出来为好,否则就是留了一个隐患;


    9-3 原型模式coding-克隆破坏单例

    让之前写的单例模式实现Cloneable接口:

    public class HungrySingleton implements Serializable,Cloneable{
        private final static HungrySingleton hungrySingleton;
        static {
            hungrySingleton = new HungrySingleton();
        }
        private HungrySingleton() {
            if (hungrySingleton != null) {
                throw new RuntimeException("单例构造器禁止反射调用");
            }
        }
        public static HungrySingleton getInstance() {
            return hungrySingleton;
        }
        /** 我们加上这样的一个方法 */
        private Object readResolve() {
            return hungrySingleton;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    测试:

    public class Test {
        public static void main(String[]args) throws CloneNotSupportedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
            HungrySingleton hungrySingleton = HungrySingleton.getInstance();
            Method method = hungrySingleton.getClass().getDeclaredMethod("clone");
            method.setAccessible(true);
            HungrySingleton cloneHungrySingleton = (HungrySingleton) method.invoke(hungrySingleton);
            System.out.println(hungrySingleton);
            System.out.println(cloneHungrySingleton);
        }
    }
    

    运行结果:

    com.ldc.design.pattern.creational.singleton.HungrySingleton@34c45dca
    com.ldc.design.pattern.creational.singleton.HungrySingleton@52cc8049


    如果我们想要克隆不破坏单例,那么我们可以这样做:

    public class HungrySingleton implements Serializable,Cloneable{
        private final static HungrySingleton hungrySingleton;
        static {
            hungrySingleton = new HungrySingleton();
        }
        private HungrySingleton() {
            if (hungrySingleton != null) {
                throw new RuntimeException("单例构造器禁止反射调用");
            }
        }
        public static HungrySingleton getInstance() {
            return hungrySingleton;
        }
        /** 我们加上这样的一个方法 */
        private Object readResolve() {
            return hungrySingleton;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return getInstance();
        }
    }
    

    现在的运行结果:这个时候,是同一个对象,还是单例的

    com.ldc.design.pattern.creational.singleton.HungrySingleton@34c45dca
    com.ldc.design.pattern.creational.singleton.HungrySingleton@34c45dca


    如何防止克隆不破坏单例模式:
    1.要么不实现Cloneable接口
    2.要么实现了Cloneable接口,但是在重写的方法clone方法里面获得对象的实例

    这样的话,就不怕克隆破坏单例模式了;


    9-4 原型模式源码解析

    在这里插入图片描述


    在这里插入图片描述


    我们查看一下它的实现:
    在这里插入图片描述


    在这里插入图片描述
    那它是如何重写的呢?
    在这里插入图片描述

    展开全文
  • Java设计模式精讲—慕课网—课程笔记1 1 课程导学 2 UML急速入门 2.1 本章导航 2.2 UML类图讲解 2.3 UML类图讲解-自上而下、对比讲解联想记忆 1 课程导学 学习方式: 设计模式定义 -> 设计模式应用 -> 源码解析 -> ...

    1 课程导学

    1. 学习方式
      设计模式定义 -> 设计模式应用 -> 源码解析 -> 系统学习设计模式;
    2. 动态递进式讲解(场景 – UML - 代码);
      采用Debug方式及内存分析;
      更容易理解抽象的设计模式;
      JDK及热门开源框架解析;
      领略设计模式的妙用技巧;
    3. 课程安排
      UML入门(UML基础、UML类图、UML时序图、UML类关系、UML记忆技巧);
      7大设计原则(开闭原则、依赖倒置原则、单一职责原则、接口隔离原则、迪米特原则、里氏替换原则、合成复用原则);
      设计模式 – 创建型模式(工厂方法模式、抽象工厂模式、建造者模式、单例模式、原型模式);
      设计模式 – 结构型模式(适配器模式、装饰者模式、代理模式、外观模式、桥接模式、组合模式、享元模式);
      设计模式 – 行为型模式(策略模式、观察者模式、责任链模式、备忘录模式、模板方法模式、迭代器模式、中介者模式、命令模式、访问者模式、解释器模式、状态模式);

    2 UML急速入门

    2.1 本章导航

    1. UML定义:统一建模语言(Unified Modeling Language);
      非专利的第三代建模和规约语言;
    2. UML特点
      UML是一种开放的方法;
      用于说明、可视化、构建和编写一个正在开发的面向对象的、软件密集系统的制品的开放方法;
      UML展现了一系列最佳工程实践,这些最佳实践在对大规模、复杂系统进行建模方面,特别是在软件架构层次已经被验证有效;
    3. UML2.2分类
      结构式图形:强调的是系统式的建模;
      行为式图形:强调系统模型中触发的事件;
      交互式图形:属于行为式图形子集合,强调系统模型中资料流程;
      一共定义了14种图示:
      结构式图形:静态图(类图,对象图,包图),实现图(组件图,部署图),剖面图,复合结构图;
      行为式图形:活动图,状态图,用例图;
      交互式图形:通信图,交互概述图(UML2.0),时序图(UML2.0),时间图(UML2.0);
    4. UML类图
      Class Diagram:用于表示类、接口、实例等之间相互的静态关系;
      虽然名字叫类图,但类图中并不只有类,包括权限、属性、方法等;
    5. 记忆技巧
      UML箭头方向:子类指向父类;(只有知道对方信息时才能指向对方)
      实线继承,虚线实现;(空心三角箭头:继承或实现,虚线无实体)
      实线关联,虚线依赖;(<>箭头)
      实心菱形组合,空心菱形聚合;(生命周期不一定,弱关系;生命周期一致,强关系)
    6. 常见数字表达及含义,假设有A类和B类,数字标记在A类侧:
      0…1: 0或1个实例;
      0…* : 0或多个实例;
      1…1: 1个实例;
      1 : 1个实例;
      1…*: 至少有1个实例;
    7. UML时序图
      Sequence Diagram:显示对象之间交互的图,对象按时间顺序排列;
      建模元素主要有对象Actor、生命线Lifeline、控制焦点Focus of control、消息Message等;

    2.2 UML类图讲解

    在这里插入图片描述

    1. 第一行:类名(抽象类:斜体;接口:尖括号+字母interface 或 棒棒糖表示法);
      第二行:类的属性
      第三行:类的行为
    2. 权限:+public,-private,#protected,无(~)default;
      冒号后面:类型/返回值;
      斜体:抽象类;
      下划线:static;

    2.3 UML类图讲解-自上而下、对比讲解联想记忆

    在这里插入图片描述

    展开全文
  • 备忘录模式22-1 备忘录模式讲解22-2 备忘录模式coding一、 模式定义二、 模式结构三、 模式实现四、 模式的优缺点五、 模式适用场景六、 模式总结22-3 备忘录模式源码解析-spring 22-1 备忘录模式讲解 22-...

    22-1 备忘录模式讲解

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    22-2 备忘录模式coding

    一、 模式定义

    ​ 所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

    ​ 备忘录模式将要保存的细节给封装在备忘录中,就是天要改变保存的细节也不会影响到客户端。

    二、 模式结构

    ​下图是备忘录模式的UML结构图:
    在这里插入图片描述


    ​ 备忘录模式主要包含入下几个角色:
    Originator: 原发器。负责创建一个备忘录,用以记录当前对象的内部状态,通过也可以使用它来利用备忘录恢复内部状态。同时原发器还可以根据需要决定Memento存储Originator的那些内部状态。

    Memento: 备忘录。用于存储Originator的内部状态,并且可以防止Originator以外的对象访问Memento。在备忘录Memento中有两个接口,其中Caretaker只能看到备忘录中的窄接口,它只能将备忘录传递给其他对象。Originator可以看到宽接口,允许它访问返回到先前状态的所有数据。

    Caretaker: 负责人。负责保存好备忘录,不能对备忘录的内容进行操作和访问,只能够将备忘录传递给其他对象。
    ​ 在备忘录模式中,最重要的就是备忘录Memento了。我们都是备忘录中存储的就是原发器的部分或者所有的状态信息,而这些状态信息是不能够被其他对象所访问了,也就是说我们是不可能在备忘录之外的对象来存储这些状态信息,如果暴漏了内部状态信息就违反了封装的原则,故备忘录是除了原发器外其他对象都是不可以访问的。

    ​ 所以为了实现备忘录模式的封装,我们需要对备忘录的访问做些控制:

    ​ 对原发器:可以访问备忘录里的所有信息。

    ​ 对负责人:不可以访问备忘录里面的数据,但是他可以保存备忘录并且可以将备忘录传递给其他对象。

    ​ 其他对象:不可访问也不可以保存,它只负责接收从负责人那里传递过来的备忘录同时恢复原发器的状态。

    ​ 所以就备忘录模式而言理想的情况就是只允许生成该备忘录的那个原发器访问备忘录的内部状态。

    典型的备忘录代码如下:

    class Memento {
        private String state;
        public Memento(Originator o){
          state = o.state;
        }
        public void setState(String state){
           this.state=state;
        }
        public String getState(){
           return this.state;
        }  
    }
    

    三、 模式实现

    ​ 实现场景:我们就以游戏挑战BOSS为实现场景,在挑战BOSS之前,角色的血量、蓝量都是满值,然后存档,在大战BOSS时,由于操作失误导致血量和蓝量大量损耗,所以只好恢复到刚刚开始的存档点,继续进行大战BOSS了。这里使用备忘录模式来实现。UML结构图如下:
    在这里插入图片描述


    ​ 首先是游戏角色类:Role.java

    public class Role {
        private int bloodFlow;//血量
        private int magicPoint;//蓝量
    
        public Role(int bloodFlow,int magicPoint){
            this.bloodFlow = bloodFlow;
            this.magicPoint = magicPoint;
        }
    
        public int getBloodFlow() {
            return bloodFlow;
        }
    
        public void setBloodFlow(int bloodFlow) {
            this.bloodFlow = bloodFlow;
        }
    
        public int getMagicPoint() {
            return magicPoint;
        }
    
        public void setMagicPoint(int magicPoint) {
            this.magicPoint = magicPoint;
        }
    
    
        public void display(){
            System.out.println("用户当前状态:");
            System.out.println("血量:" + getBloodFlow() + ";蓝量:" + getMagicPoint());
        }
    
    
        public Memento saveMemento(){
            return new Memento(getBloodFlow(), getMagicPoint());
        }
    
    
        public void restoreMemento(Memento memento){
            this.bloodFlow = memento.getBloodFlow();
            this.magicPoint = memento.getMagicPoint();
        }
    }
    

    ​ 备忘录:Memento.java

    class Memento {
        private int bloodFlow;
        private int magicPoint;
    
        public int getBloodFlow() {
            return bloodFlow;
        }
    
        public void setBloodFlow(int bloodFlow) {
            this.bloodFlow = bloodFlow;
        }
    
        public int getMagicPoint() {
            return magicPoint;
        }
    
        public void setMagicPoint(int magicPoint) {
            this.magicPoint = magicPoint;
        }
    
        public Memento(int bloodFlow,int magicPoint){
            this.bloodFlow = bloodFlow;
            this.magicPoint = magicPoint;
        }
    }
    

    ​ 负责人:Caretaker.java

    public class Caretaker {
        Memento memento;
    
        public Memento getMemento() {
            return memento;
        }
    
        public void setMemento(Memento memento) {
            this.memento = memento;
        }
    
    }
    

    客户端:Client.java

    public class Client {
        public static void main(String[] args) {
            //打BOSS之前:血、蓝全部满值
            Role role = new Role(100, 100);
            System.out.println("----------大战BOSS之前----------");
            role.display();
    
            //保持进度
            Caretaker caretaker = new Caretaker();
            caretaker.memento = role.saveMemento();
    
            //大战BOSS,快come Over了
            role.setBloodFlow(20);
            role.setMagicPoint(20);
            System.out.println("----------大战BOSS----------");
            role.display();
    
            //恢复存档
            role.restoreMemento(caretaker.getMemento());
            System.out.println("----------恢复----------");
            role.display();
    
        }
    }
    

    执行结果:

    ----------大战BOSS之前----------
    用户当前状态:
    血量:100;蓝量:100
    ----------大战BOSS----------
    用户当前状态:
    血量:20;蓝量:20
    ----------恢复----------
    用户当前状态:
    血量:100;蓝量:100

    这个就是现在的类图:
    在这里插入图片描述

    四、 模式的优缺点

    优点
    ​ 1、 给用户提供了一种可以恢复状态的机制。可以是用户能够比较方便地回到某个历史的状态。

    ​ 2、 实现了信息的封装。使得用户不需要关心状态的保存细节。

    缺点
    ​ 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。

    五、 模式适用场景

    ​ 1、 需要保存一个对象在某一个时刻的状态或部分状态。

    ​ 2、 如果用一个接口来让其他对象得到这些状态,将会暴露对象的实现细节并破坏对象的封装性,一个对象不希望外界直接访问其内部状态,通过负责人可以间接访问其内部状态。

    六、 模式总结

    ​ 1、 备忘录模式可以实现在不破坏封装的前提下,捕获一个类的内部状态,并且在该对象之外保存该对象的状态,保证该对象能够恢复到历史的某个状态。

    ​ 2、 备忘录模式实现了内部状态的封装,除了创建它的原发器之外其他对象都不能够访问它。

    ​ 3、 备忘录模式会占用较多的内存,消耗资源。

    22-3 备忘录模式源码解析-spring

    在这里插入图片描述


    在这里插入图片描述


    在这里插入图片描述


    展开全文
  • 工厂方法模式5-1 工厂方法讲解5-2 工厂方法coding5-3 工厂方法源码解析(jdk+logback) 5-1 工厂方法讲解 5-2 工厂方法coding 业务场景和之前的简单工厂一样,我们直接对简单工厂里面的代码进行改造: 还是一样...
  • 简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波 & 软件秘笈-设计模式那些事-郑阿奇 文章目录1、原型模式的定义原型-定义原型-类型2、原型模式的实现原型模式的通用类图原型...
  • 观察者模式21-1 观察者模式讲解 21-1 观察者模式讲解
  • 最全 java23种设计模式 Debug模式+内存分析
  • 软件设计七大原则3-1 本章导航3-2 开闭原则讲解3-3 开闭原则coding3-4 依赖倒置原则讲解+coding3-5 单一职责原则讲解3-6 单一职责原则coding3-7 接口隔离原则讲解+coding3-8 迪米特法则讲解+coding3-9 里氏替换原则...
  • Java软件设计模式精讲

    2021-06-20 22:24:49
    设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计...
  • 单例模式、工厂模式、装饰者模式、ThreadLocal设计模式、代理模式等
  • UML 类图讲解-自上而下 声明: 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. UML 定义 统一建模语言(英文:...
  • 单例模式8-1 单例模式讲解8-2 单例设计模式-懒汉式及多线程Debug实战 8-1 单例模式讲解 8-2 单例设计模式-懒汉式及多线程Debug实战 懒汉式单例: public class ...
  • 本博客是本人在学习《Java 设计模式精讲》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 1. 工厂方法讲解 定义:定义一个创建对象的接口,但让实现这个...
  • 简单记录 - 慕课网 - Java设计模式精讲 Debug方式+内存分析 文章目录第2章 UML急速入门2-1、UML简单入门UML定义UML特点UML 2.2分类UML类图理解泛化、实现理解依赖、关联理解聚合、组合UML时序图2-2、UML类 图讲解2-3...
  • 迭代器模式18-1 迭代器模式讲解18-2 迭代器模式coding18-3 迭代器模式源码解析(jdk+mybatis) 18-1 迭代器模式讲解 18-2 迭代器模式coding 我们都是会用写好的迭代器,而不会自己去手动的写一个迭代器; 有...
  • 外观模式10-1 外观模式讲解11-2 装饰者模式coding11-3 装饰者模式源码解析(spring-session mybatis jdk servlet) 10-1 外观模式讲解 11-2 装饰者模式coding 有一个积分礼物类: /** 积分礼物 */ public ...
  • java设计模式

    2013-06-06 22:11:16
    java设计模式
  • 建造者模式7-1 建造者模式讲解7-2 建造者模式coding7-3 建造者模式源码解析(jdk+guava+spring+mybatis) 7-1 建造者模式讲解 7-2 建造者模式coding 我们来建造一个视频课程: 首先,创建一个课程类: public...
  • 命令模式23-1 命令模式讲解23-2 命令模式coding 23-1 命令模式讲解 23-2 命令模式coding
  • 模板方法模式17-1 模板方法模式讲解17-2 模板方法模式coding17-3 模板方法源码解析(jdk+servlet+mybatis) 17-1 模板方法模式讲解 17-2 模板方法模式coding 我们引入一个业务场景:制作视频课程,要制作...
  • 代理模式16-1 代理模式讲解16-2 代理模式coding-静态代理-116-3 代理模式coding-静态代理-216-4 代理模式coding-动态代理16-5 代理模式源码解析(jdk+spring+mybatis) 16-1 代理模式讲解 可以理解为房东和中介的关系...
  • 策略模式19-1 策略模式讲解19-2 策略模式coding 19-1 策略模式讲解 19-2 策略模式coding 我们来引入一个业务场景:就比如网站里面在618和双十一的时候,会有各种促销,而促销就是课程的一个行为,是一个...
  • 访问者模式26-1 访问者模式讲解 26-1 访问者模式讲解

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,088
精华内容 1,635
关键字:

java设计模式精讲

java 订阅