第一部分:了解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)