精华内容
下载资源
问答
  • 工厂设计模式: ...可通过反射进行工厂模式的设计,完成动态的对象创建。 创建对象的两种方式(以Student为例): Student s = new Student(); Class c = Student.class; Object o = c.newInstance(); Stude...

    工厂设计模式:

    开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭。

    工厂模式主要负责对象创建的问题

    可通过反射进行工厂模式的设计,完成动态的对象创建。

    创建对象的两种方式(以Student为例):

    Student  s  =  new Student();

    Class c = Student.class;
    Object o = c.newInstance();
    Student s2 = (Student)o;

    //通过输入流获取全限定名
    FileReader fr = new FileReader("Files\\properties.txt");
    BufferedReader br = new BufferedReader(fr);
    String str = br.readLine();
    Object oo = createObject(str);

    //创建对象!
    //工厂:创建对象工厂
    public static Object createObject(String str){
           try {
                Class c = Class.forName(str);
                Object o = c.newInstance();
                return o;//通过一系列的转换返回一个Object对象
           } catch (Exception e) {
              e.printStackTrace();
           }
           return null;
    }

     

    invoke:

    一:通过Class类对象去调用对象的方法:

    //反射 类的对象
    Object o = createObject("com.qf.day35.t1.reflects.Student");
    //类对象
    Class c =o.getClass();
    //name->方法名 ,parameterTypes ->参数列表类型
    Method m = c.getMethod("study",null);
    //通过invoke方法,执行某个实例方法,参数:Object->所需对象,args->调用的方法所需的实参
    m.invoke(o, null);

    二:通过方法输入对象,形参类型和实参:

    Object o = TestInvoke.createObject("com.qf.day35.t0.invoke.Student");//获取对象
    invokeAny(o,"exam",new Class[]{int.class,double.class,String.class},1,90,"赵公民");
    invokeAny(o, "study",null,null);//调用invokeAny()方法执行其中的方法

     

    //通用编程(调用任何一个方法)
    public static void invokeAny(Object obj,String methodName,Class[] types,Object... args) throws Exception {
    //使用反射技术执行任何方法
    //类对象
    Class c = obj.getClass();
    //获得方法的对象Method
    Method m = c.getDeclaredMethod(methodName, types);
    //执行方法
    m.invoke(obj, args);
    }

     

     

    展开全文
  • 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 设计模式的六原则 开闭原则:对扩展开放,对修改关闭 ...

    在介绍设计模式之前,先贴一下设计模式的三种类型,和六大原则。

    • 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。
    • 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
    • 行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

    设计模式的六原则

    • 开闭原则:对扩展开放,对修改关闭
    • 里氏代换原则:任何基类可以出现的地方,子类一定可以出现,(子类代换基类)
    • 依赖倒转原则:对接口编程,依赖于抽象,而不依赖于具体
    • 接口隔离原则:使用多个隔离的接口,比使用单个好,降低耦合度
    • 合成复用原则:尽量使用合成/聚合的方式,而不是使用继承
    • 迪米特法则(最少知道原则):实体之间尽量少发生相互作用,使模块相对独立

    下面开始介绍最简单常见的单例模式

    使用场景:一个类全局只有一个实例的情况。该实例由单例类自己创建,并提供访问该实例的方法。使用单例类一般是实例创建比较复杂的情况,且对象不保存状态信息(即没有可供修改的成员变量,否则很容易被修改)。可以将单例类理解成一个工具类,提供全局访问,只有一个实例。Spring中的bean默认使用的就是单例模式。

    下面开始介绍单例模式的六种实现

    饿汉模式

    饿汉模式是在类被加载的时候就创建了实例,即使这个单例都不一定会被使用。

    public class Singleton{
        private Singleton(){}    // 构造方法私有化
        private static final Singleton instance = new Singleton();       // 实例在类加载时就被创建 
        public static Singleton getInstance(){
            return instance;
        }
    }
    

    懒汉模式

    懒汉模式是在只有单例类被使用的时候才创建出来。

    public class Singleton {
    	private Singleton(){}
    	private static Singleton instance = null;	// 默认为null
    	public static Singleton getInstance(){
    		if (instance == null) {				// 方法被调用的时候才创建
    			instance = new Singleton();
    		}
            return instance;
        }
    }
    

    线程安全的懒汉模式

    在多线程环境下,上面的懒汉模式,很容易创建出多个实例。于是需要加锁。加一个synchronized就不会有多线程创建多个实例了。

    public class Singleton {
    	private Singleton(){}
    	private static Singleton instance = null;	// 默认为null
    	public static synchronized Singleton getInstance(){
    		if (instance == null) {				// 方法被调用的时候才创建
    			instance = new Singleton();
    		}
            return instance;
        }
    }
    

    双重检验锁 的懒汉模式

    既然是多线程环境下,直接在方法上加synchronized,那效率就很低了,肯定不满足要求。所以需要在内部创建对象的时候才加锁。

    但是看下面的代码,我们发现在获取到锁开始创建对象前,又进行了一次非空校验。这个应该很好理解吧,在创建时加锁只是让线程一个一个进去。两个线程同时访问,第一个获取到锁的线程进去创建了实例后,第二个进入,如果不判空,第二个还是会创建另一个实例。双重校验锁在平时写代码中很常见(划重点)

    然后其实只有一个应该注意的是 volatile 关键字,该关键字能够防止java指令重排序。instance = new Singleton();在jvm中包含多个操作(划分一块内存 ->在内存上创建对象 -> 将instance指向对应内存等),然后进过jvm重排序后,可能就是 (划分一块内存 -> 将instance指向对应内存等 -> 在内存上创建对象) 这样的话,就会返回一个没有实例化完全的对象了,比如null。

    public class Singleton {
        private Singleton(){}
        private static volatile Singleton instance = null;
        public static synchronized Singleton getInstance(){
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    静态内部类模式 (登记式)

    这种方法也是在使用时才实例化。但看代码里面貌似直接new了。这是利用了静态内部类的特性,只有在访问静态内部类时,它才会被加载。

    public class Singleton{
        private static class Inner{
            private static final Singleton instance= new Singleton();
        }
        private Singleton();
        public static Singleton getInstance(){        //调用该方法时,Inner类才会被加载,然后实例化instance
            return Inner.instance; 
        }
    }
    

    枚举类模式

    最简单粗暴的方式当然是我们的枚举类了。都不需要写getInstance方法,直接 Singleton.instance 访问。

    public enum Singleton{
        instance;
    }
    

    这样咋一看,感觉枚举类和饿汉模式差不多嘛。不不不,在反射面前,前面5中模式都是渣渣。只有枚举类不能通过反射修改构造方法。

    public static void main(String[] args)  {
       Class<Singleton> aClass = Singleton.class;
        try {
            Constructor<Singleton> constructor = aClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            Singleton singleton = constructor.newInstance();
            Singleton singleton2 = constructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    然后看到有人说,加一个类变量,然后调用构造方法时判断其状态,如果时第二次就抛异常。比如下面这样

    public class Singleton {
        private static boolean init = false;
        private Singleton(){
            if (init) {
                throw new RuntimeException();
            }
            init = true;
            System.out.println("hahah");
        }
        private static Singleton instance = new Singleton();
    
        public static Singleton getInstance() {
            return instance;
        }
    }
    

    天真!以为反射只能修改构造方法的可见性?

    public static void main(String[] args)  {
        Class<Singleton> aClass = Singleton.class;
        try {
            Constructor<Singleton> constructor = aClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            Field init = aClass.getDeclaredField("init");
            init.setAccessible(true);
            init.setBoolean(null, false);
            Singleton singleton = constructor.newInstance();
            init.setBoolean(null, false);
            Singleton singleton2 = constructor.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    展开全文
  • 目录介绍传统工厂模式工厂模式结合反射机制总结 介绍 工厂模式是一种创建型模式,在工厂模式中,创建对象时不会对客户端暴露创建细节(将创建的代码封装到一个工厂类中),而是通过一个接口指向由工厂类创建并返回的...

    介绍

    工厂模式是一种创建型模式,在工厂模式中,创建对象时不会对客户端暴露创建细节(将创建的代码封装到一个工厂类中),而是通过一个接口指向由工厂类创建并返回的对象。
    对于设计模式和各个原则来说,无非就是要实现代码的高内聚和低耦合,还有尽量遵循开闭原则。开闭原则简单来说就是:软件中的对象(类,函数,模块)对扩展开放,对修改关闭。

    于是,围绕开闭原则展开以下讨论。
    传统工厂模式是如何违背了开闭原则的,工厂模式加反射机制是如何遵循开闭原则的。

    以披萨为话题,我们要创建各种口味的披萨,例如奶酪披萨,水果披萨。
    这个显然可以就通过工厂模式来实现,下面用传统工厂模式。
    首先我们要声明一个IPizza接口:

    public interface IPizza {
        void eat();
    }
    

    IPizza的实现类:

    //奶酪披萨
    public class CheesePizza implements IPizza {
        private String pizzaType="奶酪披萨";
        @Override
        public void eat() {
            System.out.println(pizzaType+"真香!");
        }
    }
    
    //水果披萨
    public class FruitPizza implements IPizza {
        private String pizzaType="水果披萨";
        @Override
        public void eat() {
            System.out.println(pizzaType+"真好吃!");
        }
    }
    

    下面通过工厂创建各种口味的披萨。

    传统工厂模式

    写一个工厂类,把创建各种口味披萨的任务交给它。

    //披萨工厂类
    public class PizzaFactory {
        private PizzaFactory(){}
        public static IPizza createPizza(String pizzaType){
            IPizza pizza=null;
            if ("奶酪披萨".equals(pizzaType)) {
                pizza=new CheesePizza();
            } else if ("水果披萨".equals(pizzaType)) {
                pizza=new FruitPizza();
            }
            return pizza;
        }
    }
    

    测试:

    public class PizzaTest {
        public static void main(String[] args) {
            IPizza pizza=PizzaFactory.createPizza("水果披萨");
            pizza.eat();
            pizza=PizzaFactory.createPizza("奶酪披萨");
            pizza.eat();
        }
    }
    

    控制台结果:
    在这里插入图片描述
    OK!就是那么简单,但是问题来了,我现在突然想到还有一种口味的披萨:蛋黄披萨。我想把它添加到系统中,要怎么做呢?
    第一步,实现IPizza接口

    //蛋黄披萨
    public class EggyolkPizza implements IPizza {
        private String pizzaType="蛋黄披萨";
        @Override
        public void eat() {
            System.out.println(pizzaType+"贼香!");
        }
    }
    

    第二步,修改工厂类(emmm,思考一下,这是不是违背了开闭原则)

    修改过程就是添加一个else if分支。

    public class PizzaFactory {
        private PizzaFactory(){}
        public static IPizza createPizza(String pizzaType){
            IPizza pizza=null;
            if ("奶酪披萨".equals(pizzaType)) {
                pizza=new CheesePizza();
            } else if ("水果披萨".equals(pizzaType)) {
                pizza=new FruitPizza();
            } else if ("蛋黄披萨".equals(pizzaType)) {
                pizza=new EggyolkPizza();
            }
            return pizza;
        }
    }
    

    代码搞定,测试一下:
    在这里插入图片描述
    添加披萨口味是成功了,但是我们也违背了开闭原则,如果有很多个口味的披萨引进来,那我们岂不是要改工厂类改到吐?

    工厂模式结合反射机制

    同样也是写一个工厂类,把创建各种口味披萨的任务交给它。

    public class PizzaFactory {
        private PizzaFactory(){}
        public static IPizza createPizza(String pizzaType){
            IPizza pizza=null;
            try {
                Class clazz=Class.forName(pizzaType);
                pizza=(IPizza)clazz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return pizza;
        }
    }
    

    测试:

    public class PizzaTest {
        public static void main(String[] args) {
            IPizza pizza=PizzaFactory.createPizza("cn.thg.community.pizza.impl.CheesePizza");
            pizza.eat();
            pizza=PizzaFactory.createPizza("cn.thg.community.pizza.impl.FruitPizza");
            pizza.eat();
        }
    }
    

    控制台结果:
    在这里插入图片描述
    OK!
    添加一个口味的披萨,还是蛋黄披萨吧。
    很简单,只需要扩展多一个类就行了,不需要取修改工厂类。
    只需一步,扩展一个蛋黄披萨的类

    public class EggyolkPizza implements IPizza {
        private String pizzaType="蛋黄披萨";
        @Override
        public void eat() {
            System.out.println(pizzaType+"贼香!");
        }
    }
    

    测试:
    在这里插入图片描述
    搞定。这样无论要加多少种口味,只需要拓展就行了,这不就很好的遵循了开闭原则吗,无论添加多少个披萨类,都不用对工厂类进行任何改变,直接在客户端(main方法)调用即可,相比较与传统工厂模式简直不要方便太多。

    总结

    很显然,传统工厂模式违背了开闭原则(扩展新口味要修改工厂类),而工厂模式结合反射的方式则没有违背。只不过是后者传参的方式变成了传全限定类名。

    展开全文
  • Java工厂模式和通用编程1. 工厂模式2. 通用编程 ...可通过反射进行工厂模式的设计,完成动态的对象创建。 public class TestNewInstanceForFile { public static void main(String[] args) thr...

    Java工厂模式和通用编程

    1. 工厂模式

    • 开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭;
    • 工厂模式主要负责对象创建的问题;
    • 通过反射进行工厂模式的设计,完成动态的对象创建
    public class TestNewInstanceForFile {
          public static void main(String[] args) throws Exception {
                // 创建出入流对象
                FileReader fr = new FileReader("files\\application.txt");
                BufferedReader br = new BufferedReader(fr);
                // 读出文件中的类的全限定名
                String className = br.readLine();
                
                // 创建Object对象返回后进行强转为对应类型,进而使用
                Teacher t3 = (Teacher)createObject(className);
                System.out.println(t3);
                
                br.close();
          }
          
          /**
           * 工厂:创建对象工厂
           * @param className String类型的类的全限定名
           * @return Object Object类型的对象
           */
          public static Object createObject(String className) {
                try {
                      Class<?> c = Class.forName(className);
                      return c.newInstance();
                } catch (Exception e) {
                      e.printStackTrace();
                }
                return null;
          }
    }
    /*
    * files\\application.txt 内容:
    * com.methods.Teacher
    */
    

    2. 通用编程

    使用反射机制,实现执行任何类的任意方法。

    突破封装示例:

                // 反射:类的对象
                Object o = createObject("com.day.t1_factory.Student");
                // 类对象
                Class<?> c = o.getClass();
                Method m = c.getDeclaredMethod("calc", null); // 获取自身方法,包含私有方法
                // 【注意】反射是一种底层技术,可取消语言检查,突破private封装!
                // AccessibleObject类:@true 忽略Java语言访问检查 @false 反之
                m.setAccessible(true); 
                m.invoke(o, null);
    

    调用任意类的任意方法的演示:

    public class TestInvokeAnything {
          public static void main(String[] args) throws Exception {
                // invokeAny() 执行任何方法
                // 传入:对象(Object)、方法名称(String)、形参(.class)、实参(Object)
                invokeAny(
                              createObject("com.day.t1_factory.Student"),
                              "exam",
                              new Class[] {int.class, double.class,  String.class},
                              2, 10, "小明"
                             ); // public void exam(int n, double score,  String name)
                
                Object o = createObject("com.day.t1_factory.Student");
                invokeAny(o, "study", null, null); // public void study()
                invokeAny(o, "study", new Class[] {Integer.class}, 100); //  public int study(Integer a)
                
          }
          /**
           * 反射技术,执行任何方法
           * @param obj Objcet类型对象
           * @param methodName String类型方法名称
           * @param types Class[]数组类型的types
           * @param args Object类型的可变长参数
           * @throws Exception
           */
          public static void invokeAny(Object obj, String methodName,  Class<?>[] types, Object...args) throws Exception {
                Class<?> c = obj.getClass(); // 1.获取类对象
                Method m = c.getDeclaredMethod(methodName, types); // 2.获得方法的对象Method
                m.invoke(obj, args); // 3.执行方法
          }
          /**
           * 反射技术,工厂设计模式
           * @param className 类的全限定名
           * @return 返回Object类型的对象
           */
          public static Object createObject(String className) {
                try {
                      Class<?> c = Class.forName(className);
                      return c.newInstance();
                } catch (Exception e) {
                      e.printStackTrace();
                }
                return null;
          }
    }
    
    展开全文
  • 文章目录设计原则、设计模式类加载反射JDK动态代理 设计原则、设计模式 面向对象思想设计原则 单一职责原则:每个类应该只有一个职责,对外只能提供一种功能。其实就是”高内聚,低耦合”。 开闭原则:对扩展开放...
  • 物理安装 PCI反射内存 兼容的系统外观不同,并且有不同的安装流程,建议安装前 检查主机系统的安装程序,以下步骤简单的描述了一个 ...所需的模式。 确保 PCI 连接器正确插入,安装螺丝。 关闭机箱,接通电源。 ...
  • 设计模式

    2020-10-16 10:41:09
    可以通过反射进行工厂设计模式的设计,完成动态的对象创建 /** * 父类产品 * @author ASUS * */ public interface Usb { void service(); } public class Upan implements Usb{ @Override public void ...
  • 在实际使用过程中,违背了开放-关闭原则,当然有些情况下可以通过反射调用来弥补这种不足。 抽象工厂模式:  提供一个创建——系列相关相互依赖对象的接口,而无需指定他们具体的类。抽象工厂为不同产...
  • 关闭流时只需要关闭最外层的流。字节流和字符流之间的转换: InputStreamReader需要和InputStream套接;OutputStreamWriter需要和OutputStream套接。 2.反射机制 java的反射机制允许程序在运行时加载、探知、使用...
  • 工厂设计模式

    2020-08-18 01:23:00
    什么是设计模式 一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。简单理解:特定问题的固定解决方法。 好处:使用设计模式是...可通过反射进行工厂模式的设计,完成动态的对象创建。 工厂类...
  • /** * 懒汉模式(一) * @author moke */ public class LazyModeA { private volatile static LazyModeA instance = null;... * 关闭new方式实例化(然后还是能通过反射创建的......) */ p...
  • /** * 懒汉模式(二)特别 * @author moke */ public class LazyModeB { private volatile static LazyModeB instance = null;... * 关闭new方式实例化(然后还是能通过反射创建的......) */ ...
  • 代理模式:对其他对象提供一种代理,来控制对这个对象的访问 分类: ...(1)设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻...
  • (1)设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,...
  • java 工厂模式的应用

    2020-06-17 09:16:43
    可通过反射进行工厂模式的设计,完成动态的对象创建 package ch3; //产品家族 abstract class Car{ private String brand; public Car() { } public Car(String brand) { this.brand = brand; } public ...
  • 大话设计模式

    2017-08-10 23:50:00
    这样的好处就是,不用在工厂类里new对象,对修改关闭.可以通过反射来创建新的对象,对扩展开放. 5.原型模式 就是一个类提供clone方法(可以实现IConleable),利用this.MemberwiseClone()实现浅复制...
  • 上一章内容,java 反射机制 常用设计原则和设计模式 常用的设计原则 软件开发的流程 需求分析文档、概要设计文档、详细设计文档、编码和测试、安装和调试、维护和升级 常用的设计原则 开闭原则(Open Close ...
  • 色彩理论和图层混合模式

    千次阅读 2010-11-09 20:03:00
    色彩理论和图层混合模式 一、RGB颜色CMYK颜色  我们首先看一下实验的环境。这是一个四周墙壁全是白色的封闭的房间,我们就用它来研究色光的混合。现在房间里开着灯,我们可以看到各面墙壁 将...
  • Android AP模式创建有/无密码热点

    千次阅读 2016-10-20 16:15:55
    1、用到的类(可以不用反射) WifiManager:控制wifi的状态监测和打开、关闭。 WifiConfiguration:配置wifi的用户名、密码和加密方式等。 KeyMgmt:设置加密的方式,并设置到config中 2、...
  • 一个软件实体对扩展开放,对修改关闭,即在不修改源代码的情况下改变这个模块的行为 方式:配置文件,DOM解析,反射 2、里氏替换原则 如果能够使用基类对象,那么一个能够使用子类对象,把基类都替换成子类,程序...
  • 工厂用来生产对象,对象具有方法和属性。 简单工厂的缺点(简单工厂并不是23中设计模式): ...改进方法:能够直接通过反射去改进简单工厂的开闭原则(对扩展开放,对修改关闭); 工厂方法: 定...
  • java.sql.SQLException: 关闭的连接 at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java :125) at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java :162) ...
  • 代理模式(通过代理静默地解决一些业务无关的问题,比如远程、安全、事务、日志、资源、关闭……让应用开发者可以只关心他的业务) 静态代理:事先写好代理类,可以手工编写,也可以用工具生成。缺点是每个业务类都...
  • 代理模式(通过代理静默地解决一些业务无关的问题,比如远程、安全、事务、日志、资源关闭……让应用开发者可以只关心他的业务)  静态代理:事先写好代理类,可以手工编写,也可以用工具生成。缺点是每个业务类都...
  • 千锋逆战班学习日志

    2020-03-20 20:20:07
    千锋逆战班学习第34天总结-反射总结-反射 千锋逆战班学习第34天 努力或许没有收获,但不努力一定没收获,加油。 今天我学了Java课程的反射和JDK8。...可通过反射进行工厂模式的设计,完成动态的对象创建。...
  • 2020-03-23

    2020-03-23 19:01:45
    Java工厂模式和通用编程 工厂模式2. 通用编程1....可通过反射进行工厂模式的设计,完成动态的对象创建。public class TestNewInstanceForFile { public static void main(String[] args) throws Excep...
  • 不想面试一

    2018-10-21 16:38:11
    final 修饰不可变变量,不可覆盖...反射的用途实现 通过反射机制可以在运行期间获取对象的类型信息 (工厂模式,代理模式等),解决java泛型擦除等 获取一个对象的反射类 getClass() Class.forName() 类.class ...
  • ① 把图像采样器改为“固定模式“,把抗锯齿系数调低,并关闭材质反射、折射和默认灯。 ② 勾选GI,将“首次反射”调整为lrradiance map模式(发光贴图模式),调整min rate(最小采样)和max rate(最大采样)为-6,-5...

空空如也

空空如也

1 2 3 4 5
收藏数 82
精华内容 32
关键字:

关闭反射模式