20180206 反射中模块化开发的上课思路

一、写Dao文件

package cn.sgy.reflection1.exer;

public interface Dao {

    public void insert(User user) ;
    public void delete(User user); 
}

二、写MySQLDao文件,实现Dao 接口后重写Dao的方法

package cn.sgy.reflection1.exer;


public class MySQLDao implements Dao{


    @Override
    public void insert(User user) {
        System.out.println("向MySQL插入用户对象:"+ user.getName());
    }

    @Override
    public void delete(User user) {
        System.out.println("从MySQL中删除用户对象:"+ user.getName());
    }
    
    

}

三、写OracleDao文件,实现Dao 接口后重写Dao的方法

package cn.sgy.reflection1.exer;

public class OracleDao implements Dao{

    @Override
    public void insert(User user) {
        System.out.println("向Oracle中插入用户:"+ user.getName());
    }

    @Override
    public void delete(User user) {
        System.out.println("从Oracle中删除用户:"+ user.getName());
    }

}

四、写User用户类

package cn.sgy.reflection1.exer;

import java.sql.Date;

public class User {

    
    
    private String name;
    private int age;
    private char gender;
    private Date birth;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public char getGender() {
        return gender;
    }
    public void setGender(char gender) {
        this.gender = gender;
    }
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    
    
    
}

五、【重点】Service层,也分别写insert 和delete 方法

1、最开始 每次换数据库都要修改代码 重启程序

package cn.sgy.reflection1.exer;

public class Service {

    public void insert() {

        
        User user = new User();
        
        MySQLDao dao = new MySQLDao();
        
        dao.insert(user);
    }
    

    public void delete() {
        
        User user = new User();
        
        MySQLDao dao = new MySQLDao();
        
        dao.delete(user);
    }
    public static void main(String[] args) {
    
        Service s= new Service();
    
        s.insert();
}    
    
}

2、把dao的定义提到两个方法的外面 依然很麻烦 

package cn.sgy.reflection1.exer;

public class Service {

    private Dao dao = new MySQLDao();public void insert() {

        
        User user = new User();
        
        
        dao.insert(user);
    }
    

    public void delete() {
        
        User user = new User();
        
        
        dao.delete(user);
    }
    public static void main(String[] args) {
    
        Service s= new Service();
    
        s.insert();
}    
    
}

3、引入properties思想(右击项目工程->new -> File)

如何调用properties,先想到的是构造函数,但是弊端在与有Service就要在每个Service类里写多少个properties方法

private Properties prop = new Properties();

核心代码

1、  prop.load(new FileInputStream("config.properties"));

2、  String name = prop.getProperty("Dao"); 

从Properties中读取字符串

3、 Class<Dao> clz = (Class<String>) Class.forName(name);

根据字符串产生Dao的字节码(用的是第三种方法)       字符串—>字节码

4、 return  clz.newInstance();

根据字节码产生对应的Dao实例对象

package cn.sgy.reflection1.exer;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

public class Service {

    private Dao dao ;
    private Properties prop = new Properties();
    {
        try {
            prop.load(new FileInputStream("config.properties"));
            
            String name = prop.getProperty("Dao");
            
            Class<Dao> clz = (Class<Dao>) Class.forName(name);
            
            dao = clz.newInstance();
            
             
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    public void insert() {

        
        User user = new User();
        
        
        dao.insert(user);
    }
    

    public void delete() {
        
        User user = new User();
        
        
        dao.delete(user);
    }
    public static void main(String[] args) {
    
        Service s= new Service();
    
        s.insert();
}    
    
}

六、如果有第二个Service那四行核心代码就又需要再写一遍 ,于是为了减少冗余 引入Factory(产生Dao的工厂)共用同一个Properties 所以一个工厂就够了,可以吧这个工厂设置为单例的

Service里面换成这个句子

private Dao dao =DaoFactory.getFactory().getDaoInsance();

这里使用的是单例饿汉式方式

// 饿汉式---在创建实例的时候就把这个实例初始化的方式
 private static TaskManager tm = new TaskManager();//先提供一个本类对像

 private TaskManager() {   //本类构造函数私有化
 }

 public static TaskManager getInstance() { //提供一个本类的获取TaskManager的方法 return tm; } 

public static void m() { } }

DaoFactory.java

package cn.sgy.reflection1.exer;

import java.io.FileInputStream;
import java.util.Properties;



//工厂模式
public class DaoFactory {

    
    private static DaoFactory factory = new DaoFactory();
    
    private Properties p = new Properties();
    
    private DaoFactory() {
        
    }
    
    public static DaoFactory getFactory() {
         
        return factory ;
        
    }
    
    @SuppressWarnings("unchecked")
    public Dao getDaoInsance() {
        try {
            p.load(new FileInputStream("config.properties"));
            
            String name =  p.getProperty("Dao");
            
            Class<Dao> clz = (Class<Dao>) Class.forName(name);
            
            return  clz.newInstance();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    
}
config.properties

Dao=cn.tedu.reflection.exer.MySQLDao
Service=cn.tedu.reflection.exer.VIPService

七、拓展 自定义 delete等方法

八、深化: 一个Service 里面一个Dao 对象  , Service不止一个   ,Service 可以和Dao解耦 ,前台获取数据之后Service来处理,不止一个Service 时候前台如何处理这么多数据?

Model.class收取数据 不能直接放入数据库 要经过UserService的校验

package cn.tedu.reflection.exer;

import java.util.Scanner;

public class Model {
//    private Service service = ServiceFactory.getFactory().getServiceInstance();

    private Service service = CommonFactory.getFactory().getInstance(Service.class);
    
    public void insertUser() {

        User user = new User();
        // Scanner s = new Scanner(System.in);
        // user.setName(s.nextLine());
        // user.setAge(Integer.parseInt(s.nextLine()));
        // user.setGender(s.nextLine().charAt(0));
        // s.close();

        user.setName("Amy");
        user.setAge(25);
        user.setGender('男');

        // 需要把User存储到数据库
        service.insert(user);
    }

    public void delUser() {

        User user = new User();
        Scanner s = new Scanner(System.in);
        user.setName(s.nextLine());
        s.close();

        UserService service = new UserService();
        service.delete(user);

    }

    public static void main(String[] args) {
        Model m = new Model();
        m.insertUser();
    }

}

把数据获取和数据处理分开

package cn.tedu.reflection.exer;

public class UserService implements Service {

//    private Dao dao = DaoFactory.getFactory().getDaoInstance();
    private Dao dao = CommonFactory.getFactory().getInstance(Dao.class);

    public void insert(User user) {
        
        System.out.println("普通客户处理中~~~");
        
        if(user == null){
            throw new NullPointerException("用户不能为空!!!");
        }
        
        if (user.getAge() < 0) {
            throw new IllegalArgumentException(user.getName() + "不合法!");
        }
        
        if (user.getGender() != '男' && user.getGender() != '女') {
          throw new IllegalArgumentException(user.getGender() + "不合法!");
        }
        
        if (user.getName() == null || user.getName().length() <= 0 || user.getName().length() > 5) {
            throw new IllegalArgumentException(user.getName() + "不合法!");
        }
        

        // 向数据库中插入数据
        dao.insert(user);

    }

    public void delete(User user) {
        dao.delete(user);
    }

}

提供Service类

package cn.tedu.reflection.exer;

public interface Service {
    
    public void insert(User user);
    public void delete(User user);

}

用UserService和VIPService实现Service

这时Model出现耦合 所以通过ServiceFactory来解决

核心代码 

private Service service = ServiceFactory.getFactory().getServiceInstance();

p.load(new FileInputStream("config.properties"));

 

String name = p.getProperty("Service");

 

Class<Service> clz = (Class<Service>) Class.forName(name);

 

return clz.newInstance();

config.properties文件


Dao=cn.tedu.reflection.exer.MySQLDao Service=cn.tedu.reflection.exer.VIPService

再产生一个更通用的Factory,通过泛型选择哪个Factory

package cn.tedu.reflection.exer;

import java.io.FileInputStream;
import java.util.Properties;

public class CommonFactory {

    private static CommonFactory factory = new CommonFactory();

    private Properties prop = new Properties();

    private CommonFactory() {
    }

    public static CommonFactory getFactory() {
        return factory;
    }

    @SuppressWarnings("unchecked")
    public <T> T getInstance(Class<T> inf) {

        try {
            prop.load(new FileInputStream("config.properties"));

            String name = inf.getSimpleName();

            Class<T> clz = (Class<T>) Class.forName(prop.getProperty(name));//获取到了键

            return clz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

}
原文地址:https://www.cnblogs.com/songyao2018/p/8424921.html