栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring从入门到入土(解耦的实现过程)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring从入门到入土(解耦的实现过程)

目录

1. 何为解耦

2. 解耦的优势

3. 未解耦

4. 使用接口解耦

5. 使用配置文件(Properties)

6. BeanFactory模式

7. 多例的测试

8. 单例的实现


1. 何为解耦
  • 让引用变量能够指向多个不同的对象(接口)

2. 解耦的优势
  • 能够在不修改源码的基础之上, 切换引用变量中的对象(符合开闭原则)
  • 低耦合意味着维护成本低, 程序的可扩展能力强 

3. 未解耦
  • 未解耦的情况下, 要想使用不同的对象就只能修改源码, 重新new出对象

 类目录结构

public class Iphone {
    public void sysName(){
        System.out.println("苹果手机!");
    }
}
public class MiPhone {
    public void sysName(){
        System.out.println("小米手机!");
    }
}
public class Man {
    public void usePhone(){
        MiPhone phone = new MiPhone();
        //Iphone phone = new Iphone();
        System.out.print("我使用");
        phone.sysName();
    }
}
public class Demo {
    public static void main(String[] args) {
        Man man = new Man();
        man.usePhone();
    }
}

 

4. 使用接口解耦
  •  使用接口解耦后, 就可以修改全类名创建不同的对象
public interface Phone {
    void sysName();
}
public class Iphone implements Phone{
    @Override
    public void sysName(){
        System.out.println("苹果手机!");
    }
}
public class MiPhone implements Phone{
    @Override
    public void sysName(){
        System.out.println("小米手机!");
    }
}
public class Man {
    public void usePhone(){
        Object obj = null;
        try {
            //使用全类名获取字节码对象
            Class aClass = Class.forName("org.example.Iphone");
            //通过字节码对象反射创建对象
            obj = aClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        //使用接口对象接上面反射创建的对象
        Phone phone = (Phone)obj;
        System.out.print("我使用");
        phone.sysName();
    }
}
public class Demo {
    public static void main(String[] args) {
        Man man = new Man();
        man.usePhone();
    }
}

5. 使用配置文件(Properties)
  •  配置文件的引入后, 不修改源码的前提下修改配置文件实现不同对象的切换

 bean.properties配置文件

#key = value
phone=org.example.MiPhone
public interface Phone {
    void sysName();
}
public class Iphone implements Phone{
    @Override
    public void sysName(){
        System.out.println("苹果手机!");
    }
}
public class MiPhone implements Phone{
    @Override
    public void sysName(){
        System.out.println("小米手机!");
    }
}
import java.io.InputStream;
import java.util.Properties;

public class Man {
    public void usePhone(){
        Object obj = null;
        try {
            //读取配置文件
            Properties ps = new Properties();
            InputStream res =
                    Man.class.getClassLoader().getResourceAsStream("bean.properties");
            ps.load(res);
            //使用key值获取value
            String beanValue = ps.getProperty("phone");

            //全类名获取字节码对象
            Class aClass = Class.forName(beanValue);
            //通过字节码对象反射创建对象
            obj = aClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Phone phone = (Phone)obj;
        System.out.print("我使用");
        phone.sysName();
    }
}
public class Demo {
    public static void main(String[] args) {
        Man man = new Man();
        man.usePhone();
    }
}

6. BeanFactory模式
  • 将读取配置文件, 创建对象等工作交给BeanFactory类, 简化Man类, Man类直接通过BeanFactory对象获取对象即可
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BeanFactory {
    //定义一个Properties对象
    private static Properties ps = new Properties();
    //静态代码块, 仅在类加载时执行一次
    static{
        //读取配置文件
        InputStream res =
                Man.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            ps.load(res);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static Object getBean(String beanId){
        Object bean = null;
        try {
            //使用key值获取value
            String beanValue = ps.getProperty(beanId);
            //全类名获取字节码对象
            Class aClass = Class.forName(beanValue);
            //通过字节码对象反射创建对象
            bean = aClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bean;
    }
}
public class Man {
    public void usePhone(){
        Phone bean = (Phone) BeanFactory.getBean("phone");
        System.out.print("我使用");
        bean.sysName();
    }
}

7. 多例的测试
  •  通过BeanFactory获取两个bean对象, 测试这两个对象是否为同一个对象
public class Man {
    public void usePhone(){
        Phone bean = (Phone) BeanFactory.getBean("phone");
        System.out.print("我使用");
        bean.sysName();

        Phone bean1 = (Phone) BeanFactory.getBean("phone");
        System.out.println("bean : "+bean);
        System.out.println("bean1: "+bean1);
        if(bean == bean1){
            //单例
            System.out.println("单例模式");
        }else{
            //多例
            System.out.println("多例模式");
        }
    }
}

8. 单例的实现
  • 通过将创建的对象存放到HashMap集合之中, 然后通过beanId将HashMap中指定的对象返回, 实现单例
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

//单例工厂
public class BeanFactorySingleton {
    //定义一个Properties对象
    private static Properties ps = new Properties();
    //创建一个hashMap对象存储创建的bean
    private static Map map = new HashMap<>();

    static{
        //读取配置文件
        InputStream res =
                Man.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            ps.load(res);
            //将配置文件中所有的key放入到Set集合中
            Set objects = ps.keySet();
            //遍历Set集合(遍历所有key)
            for (Object obj : objects) {
                //获取key
                String key = (String) obj;
                //通过key获取value
                String value = ps.getProperty(key);
                //通过value创建字节码对象
                Class aClass = Class.forName(value);
                //通过字节码对象反射创建对象
                Object bean = aClass.newInstance();
                //将key与创建的对象放入HashMap集合中
                map.put(key,bean);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Object getBean(String beanId){
       //返回map中的指定对象
       return map.get(beanId);
    }
} 
public class Man {
    public void usePhone(){
        Phone bean = (Phone) BeanFactorySingleton.getBean("phone");
        System.out.print("我使用");
        bean.sysName();

        Phone bean1 = (Phone) BeanFactorySingleton.getBean("phone");
        System.out.println("bean : "+bean);
        System.out.println("bean1: "+bean1);
        if(bean == bean1){
            //单例
            System.out.println("单例模式");
        }else{
            //多例
            System.out.println("多例模式");
        }

    }
}

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号