1. 创建对象的方式
对象的创建方式:
- 直接调用方法,创建对象:
UserService userService = new UserServiceImpl();
- 通过反射的形式,创建对象,解耦合:
Class clazz = Class.forName("com.daixiang.basic.UserserviceImpl");
UserService userservice = (UserService)clazz.newInstance();
2. 什么是工厂设计模式
- 概念:通过工厂类,创建对象
不使用工厂类时,创建对象是这样的:
User user = new User();
UserDAO userDAO = new UserDAOImpl(); - 好处:解耦合
耦合:指定是代码间的强关联关系,一方的改变会影响到另一方
问题:不利于代码维护
简单:把接口的实现类,硬编码在程序中
3. 项目案例
3.1 直接调用方法,创建对象
本次项目通过直接调用方法和使用工厂类两种不同的方法创建对象,体现出解耦合的好处及工厂类的优势。
为了达到实验效果,本次项目使用IDEA创建了一个Java项目,简单模拟实现用户登录、注册的功能。
项目的文件结构如图3-1所示,其中“BeanFactory.java”及“applicationContext.properties”是3.2节时将要创建的。
图3-1. 项目文件结构
下面是简单模拟实现用户注册、登录功能的源代码:
User.java
package com.daixiang.basic;
public class User {
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
UserDAO.java
package com.daixiang.basic;
public interface UserDAO {
// 用户注册
public void save(User user);
// 用户登录
public void queryUserByNameAndPassword(String name,String password);
}
UserDAOImpl.java
package com.daixiang.basic;
public class UserDAOImpl implements UserDAO {
// 用户注册-保存
@Override
public void save(User user) {
System.out.println("insert into user = " + user);
}
// 用户登录-查询
@Override
public void queryUserByNameAndPassword(String name, String password) {
System.out.println("query User name = " + name + " password = " + password);
}
}
UserService.java
package com.daixiang.basic;
public interface UserService {
// 用户注册
public void register(User user);
// 用户登录
public void login(String name,String password);
}
UserServiceImpl.java
package com.daixiang.basic;
public class UserServiceImpl implements UserService {
// 使用new创建UserDAOImpl对象
private UserDAO userDAO = new UserDAOImpl();
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public void register(User user) {
// 保存
userDAO.save(user);
}
@Override
public void login(String name, String password) {
userDAO.queryUserByNameAndPassword(name, password);
}
}
测试类,查看输出结果
TestSpring.java
package com.daixiang;
import com.daixiang.basic.BeanFactory;
import com.daixiang.basic.User;
import com.daixiang.basic.UserService;
import com.daixiang.basic.UserServiceImpl;
import org.junit.Test;
public class TestSpring {
@Test
public void test1(){
UserService userService = new UserServiceImpl();
userService.login("daixiang","123456");
User user = new User("zhangsan","123456");
userService.register(user);
}
}
3.2 通过简单的工厂类,创建对象
工厂设计模式下,将需要调用的类的全限定名写入配置文件。
applicationContext.properties
# Properties 集合 存储Properties文件中的内容
# 特殊的Map key = String value = String
# Properties.getProperty("userService");
userService = com.daixiang.basic.UserServiceImpl
userDAO = com.daixiang.basic.UserDAOImpl
在 UserServiceImpl
中通过工厂类 BeanFactory 的 getUserDAO() 方法创建对象,代码如下所示:
UserServiceImpl.java
package com.daixiang.basic;
public class UserServiceImpl implements UserService {
//private UserDAO userDAO = new UserDAOImpl();
// 这里通过工厂类BeanFactory的getUserDAO()方法创建对象
UserDAO userDAO = BeanFactory.getUserDAO();
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
@Override
public void register(User user) {
// 保存
userDAO.save(user);
}
@Override
public void login(String name, String password) {
userDAO.queryUserByNameAndPassword(name, password);
}
}
BeanFactory.java
package com.daixiang.basic;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
public static Properties env = new Properties();
static{
try {
// 第一步:获取IO输入流
InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
// 第二步:文件内容 封装Properties集合中key=userService value = com.daixiang.basic.UserServiceImpl
env.load(inputStream);
// 关闭流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static UserService getUserService(){
//return new UserServiceImpl();
UserService userService = null;
try {
Class clazz = Class.forName(env.getProperty("userService"));
userService = (UserService)clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return userService;
}
public static UserDAO getUserDAO(){
UserDAO userDAO = null;
try {
Class clazz = Class.forName(env.getProperty("userDAO"));
userDAO = (UserDAO)clazz.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return userDAO;
}
}
在 TestSpring
中通过工厂类 BeanFactory 的 getUserService() 方法创建对象,代码如下所示。
TestSpring.java
package com.daixiang;
import com.daixiang.basic.BeanFactory;
import com.daixiang.basic.User;
import com.daixiang.basic.UserService;
import com.daixiang.basic.UserServiceImpl;
import org.junit.Test;
public class TestSpring {
@Test
public void test1(){
//UserService userService = new UserServiceImpl();
// 这里使用了工厂类BeanFactory的getUserService()方法创建对象
UserService userService = BeanFactory.getUserService();
userService.login("daixiang","123456");
User user = new User("zhangsan","123456");
userService.register(user);
}
}
3.3 通用的工厂
通过总结3.2节简单的工厂方法,得出通用的工厂方法,代码如下所示:
BeanFactory.java
package com.daixiang.basic;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class BeanFactory {
public static Properties env = new Properties();
static{
try {
// 第一步:获取IO输入流
InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");
// 第二步:文件内容 封装Properties集合中key=userService value = com.daixiang.basic.UserServiceImpl
env.load(inputStream);
// 关闭流
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 通用的工厂方法
public static Object getBean(String name){
Object obj = null;
try {
Class clazz = Class.forName(env.getProperty(name));
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
}