1,包结构
2,User
public class User {
private int id;
private String name;
private String address;
public User() {
// TODO Auto-generated constructor stub
}
public User(int id, String name, String address) {
super();
this.id = id;
this.name = name;
this.address = address;
}
}
3,UserDAO
public interface UserDAO {
User queryById(int id);
}
4,UserDAOImpl
public class UserDAOImpl implements UserDAO {
@Override
public User queryById(int id) {
User user=null;
switch (id) {
case 1:
user=new User(1, "老雷", "武汉");
break;
case 2:
user=new User(2, "老张", "武汉");
break;
case 3:
user=new User(3, "老周", "重庆");
break;
}
return user;
}
}
5,UserService
public interface UserService {
User queryById(int id);
}
6,UserServiceImpl
public class UserServiceImpl implements UserService{
private UserDAO dao=new UserDAOImpl();
@Override
public User queryById(int id) {
return dao.queryById(id);
}
}
7,action
public class UserAction {
UserService service=new UserServiceImpl();
public void queryByid(){
User user = service.queryById(1);
System.out.println(user);
}
}
8,testAction
public class TestAction {
@Test
public void testIoc(){
UserAction action=new UserAction();
action.queryByid();
}
}
二,传统的javaEE的三法的总结
以上的写法当我要去换一个接口的实现类时就要改很多源代码,所以不难看出以上的代码耦合度太高,那有没有更好的方法来解决这个问题呢,【既然这么说,肯定是有的啦】
1,面向接口编程
目地,使用者只看接口,不管实现类,实现类交给容器【工厂factory】去创建
① 申明对象工厂解耦UserFactory
public class UserFactory {
/**
* UserDAO实现类的工厂
* @return
*/
public static UserDAO getUserDAO(){
try {
String className="com.sxt.dao.impl.UserDAOImpl";
Class clazz=Class.forName(className);
return (UserDAO) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* UserService实现类的工厂
*/
public static UserService getUserService(){
try {
String className="com.sxt.service.impl.UserServiceImpl";
Class clazz=Class.forName(className);
return (UserService) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
②使用UserFactory
不难看出以上的代码只要接口的实现发生了变化,只用去改UserFactory,但是我们开发中不可能只有一个DAO和一个Service,所以以上的写法随着项目的越来越大,Factory里面的代码会越来越多,下面我们来进一步封装
public class UserFactory {
public static <T> T getNewInstence(String bean){
try {
Class clazz=Class.forName(bean);
return (T) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
使用
以上的代码我们精减了Factory,但是在调用者端要指定类的全路径,所以要改的时候还要是去修改源代码,那么有没有办法不用去修改源代码呢,【肯定是有的】
接下来我们进一步封装
在java中properties文件和xml文件是不会被编译的,所以我们可以借助properties或者xml文件
下面我们使用properties来说明去修改
创建bean.properties
#dao config
userDAO=com.sxt.dao.impl.UserDAOImpl
#service config
userService=com.sxt.service.impl.UserServiceImpl
修改Factory
public class UserFactory {
public static <T> T getNewInstence(String bean){
try {
Properties properties=new Properties();
properties.load(UserFactory.class.getResourceAsStream("bean.properties"));
String path=properties.getProperty(bean);
Class clazz=Class.forName(path);
return (T) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
使用