Java的23设计模式学习(课时一)单例模式

简介: Java的23设计模式学习(课时一)单例模式

第一部分:了解23设计模式的概述。


1 什么是设计模式:

◆设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、

可维护性、可读性、稳健性以及安全性的解决方案。


◆1995 年,GoF (Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,

共收录了23 种设计模式,从此树立了软件设计模式领域的里程碑,人称.「GoF设计模式」。


2 学习设计模式的意义:

◆设计模式的本质是面向对象设计原则的实际运用, 是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。


◆正确使用设计模式具有以下优点:


◆可以提高程序员的思维能力、编程能力和设计能力。


◆使程序设计更加标准化、 代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。


◆使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

个人总结 增强自己编码的思维能力,以另外的一种思维解决生活中的问题。


3 GoF23设计模式指哪些:每种模式体现每一种解决问题的思想能力

◆创建型模式:


◆单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式。


◆结构型模式:


◆适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式◆行为型模式:


◆模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式。


4  0PG七大原则      

◆开闭原则:对扩展开放,对修改关闭


◆里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立


◆依赖倒置原则:要面向接口编程,不要面向实现编程。


◆单一职责原则:控制类的粒度大小、将对象解耦、 提高其内聚性。


◆接口隔离原则:要为各个类建立它们需要的专用接口


◆迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话。


◆合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。


5 Java的23设计模式的以下的内容大概介绍:

      1 创建型模式

  创建型模式 对象实例化的模式,创建型模式用于解耦对象的实例化过程。 单例模式:某个类智能有一个实例,提供一个全局的访问点。 工厂模式:一个工厂类根据传入的参量决定创建出哪一种产品类的实例。 抽象工厂模式:创建相关或依赖对象的家族,而无需明确指定具体类。 建造者模式:封装一个复杂对象的创建过程,并可以按步骤构造。 原型模式:通过复制现有的实例来创建新的实例。

      2 结构型模式

把类或对象结合在一起形成一个更大的结构。 装饰器模式:动态的给对象添加新的功能。 代理模式:为其它对象提供一个代理以便控制这个对象的访问。 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。 适配器模式:将一个类的方法接口转换成客户希望的另一个接口。 组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。 享元模式:通过共享技术来有效的支持大量细粒度的对象。

       3 行为型模式:

类和对象如何交互,及划分责任和算法。 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。 观察者模式:对象间的一对多的依赖关系。 仲裁者模式:用一个中介对象来封装一系列的对象交互。 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。 访问者模式:不改变数据结构的前提下,增加作用于一组对象元素的新功能。


第二部分:创建型模式分类中的单例模式的初步了解

单例模式的定义:Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。

案例一:饿汉式单例模式 指全局的单例实例在类装载时构建;浪费自己电脑的cpu内存:

package coms.Design.Mode.single;
//饿汉式单例模式
//指全局的单例实例在类装载时构建
public class Hungry {
    //可能浪费空间 自己定义了一块内存
    private  byte[] data1= new byte[1024*1024];
    private  byte[] data2= new byte[1024*1024];
    private  byte[] data3= new byte[1024*1024];
    //对象已经存在但是浪费Cpu的存放空间
    private  Hungry(){
    }
    private final static Hungry HUNGRY=new Hungry();
    public  static  Hungry getInstance(){
        return HUNGRY;
    }
}

案例二:在案例一的基础上对面的问题作出了改进:静态内部类的定义

package coms.Design.Mode.single;
//静态内部类的定义
public class Hoder {
    //私有的方法
    private Hoder(){
    }
    public  static  Hoder getInstance(){
        return InnerClass.HODER;
    }
    public  static  class  InnerClass{
        private static  final Hoder HODER =new Hoder();
    }
    public static void main(String[] args) {
        Hoder hoder = new Hoder();
    }
}

案例三:在案例二上进一步的思考:

package coms.Design.Mode.single;
public class LazyMan1 {
    private LazyMan1() {
        System.out.println(Thread.currentThread().getName()+"ok");
    }
    //volatile
    private  volatile  static LazyMan1 lazyMan;
    /**
     * 两重查看模式(Dcl)
     * @return
     */
    public static LazyMan1 getLazyMan() {
        if (lazyMan == null) {
            synchronized (LazyMan1.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan1();
                }
            }
            //第二次查看
//        if(lazyMan==null){
//            lazyMan=new LazyMan();
//        }
        }
        //多线程
//    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//            new Thread(()->{
//                lazyMan.getLazyMan();
//            }).start();
//        }
//    }
        return lazyMan;//此时lazyMan 还没有完成构造
    }
}

案例四在案例三的基础上进一步的理解

package coms.Design.Mode.single;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/**
 * 道高一尺
 */
public class LazyMan {
    private  static  boolean we=false;
    private LazyMan() {
        synchronized (LazyMan.class){
            if(we==false){
                we=true;
            }else
                throw  new RuntimeException("不要破坏异常");
            }
//            if(lazyMan!=null){
//                throw  new RuntimeException("不要破坏异常");
//            }
        }
//        System.out.println(Thread.currentThread().getName()+"ok");
//    }
    //volatile
    private  volatile  static LazyMan lazyMan;
    /**
     * 两重查看模式(Dcl)
     * @return
     */
    public static LazyMan getLazyMan() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();
                    /**
                     * 1 分配内存空间
                     * 2 执行构造方法
                     * 3 把这个对象指向这个空间
                     *
                     */
                }
            }
            //第二次查看
//        if(lazyMan==null){
//            lazyMan=new LazyMan();
//        }
        }
        //多线程
//    public static void main(String[] args) {
//        for (int i = 0; i < 10; i++) {
//            new Thread(()->{
//                lazyMan.getLazyMan();
//            }).start();
//        }
//    }
        return lazyMan;//此时lazyMan 还没有完成构造
    }
    //反射
    public static void main(String[] args) throws Exception {
//        LazyMan intance=LazyMan.getLazyMan();
        //私有的破坏
        Field we = LazyMan.class.getDeclaredField("we");
        we.setAccessible(true);
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor();
        //无视私有
        declaredConstructor.setAccessible(true);
        //俩个都是用了反射来new
        LazyMan intance=declaredConstructor.newInstance();
        we.set(intance,false);
        LazyMan intance2=declaredConstructor.newInstance();
        System.out.println(intance);
        System.out.println(intance2);
    }
}

案例五:在对单例模式更深层次的理解:

package coms.Design.Mode.single;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//  是一个什么  本身也是一个类
public enum   EnumSingle {
    INSTANSINGLE;
    public  EnumSingle getInstansingle(){
        return INSTANSINGLE;
    }
}
/**
 * Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
 *  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
 *  at coms.Design.Mode.single.Test.main(EnumSingle.java:22)
 *
 *  没据 不能 破坏 单例
 */
class Test{
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        EnumSingle instanSingle1 =EnumSingle.INSTANSINGLE;
        Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingle instanSingle2 = declaredConstructor.newInstance();
        //没有空参构造
        System.out.println(instanSingle1);
        System.out.println(instanSingle2);
    }
}
"C:\Program Files\Java\jdk1.8.0_171\bin\java.exe" "-javaagent:D:\IDEA\com.text\IntelliJ IDEA 2020.1.2\lib\idea_rt.jar=52855:D:\IDEA\com.text\IntelliJ IDEA 2020.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_171\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_171\jre\lib\rt.jar;D:\SSM\com.JavaBasics\out\production\com.JavaBasics" coms.Design.Mode.single.Test
Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
  at coms.Design.Mode.single.Test.main(EnumSingle.java:29)
Process finished with exit code 1

总结的结论:线程“main”java.lang.IllegalArgumentException中的异常:无法反射式创建枚举对象


在java.lang.reflect.Constructor.newInstance(constructure.java:417)


在coms.Design.Mode.single.Test.main中(EnumSingle.java:29)

相关文章
|
8天前
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
|
14天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
20 2
|
17天前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
28天前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
32 4
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
1月前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
19天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
28天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
25 0
|
1月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
6月前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
71 4