三层架构中 工厂模式和单例模式的使用

工厂模式和单例模式的使用

    在上一篇中简单的说明一下三层架构,为了对数据访问层进一步封装,可以采用工厂模式和单例模式,其中工厂负责生产UserDao的具体实现类,而在一个应用中实现类有一个就够了,所以采用单例模式。

    首先,创建配置文件daoconfig.properties,内容如下:     
UserDaoImpl=xxx.xxx.UserDaoJdbcImpl
//UserDaoIBatisImpl=xxx.xxx.UserDaoIBatisImpl

    创建UserDaoFactory,内容如下:     
public class UserDaoFactory
{
	private static UserDao userDao = null;
	private static UserDaoFactory instance = new UserDaoFactory();
		
	/**
	 * 构造方法私有
	 */
	private UserDaoFactory(){

		Properties prop = new Properties();
		try
		{
			//加载配置文件
			prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
			//获得数据访问层的实现类
			String userDaoClass = prop.getProperty("UserDaoImpl");
			//通过反射获得实现类的一个对像
			userDao = Class.forName(userDaoClass).newInstance();
			
		}catch (IOException e)
		{
			e.printStackTrace();
		} catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}		
	}
	
	/**
	 * 返回类的实例
	 * @return
	 */
	public UserDaoFactory getInstance(){
		return instance;
	}
	
	/**
	 * 返回UserDao的一个实例
	 * @return
	 */
	public UserDao getUserDao(){
		return userDao;
	}
}

    上述是工厂模式和单例模式的合集,在应用层,代码如下:     
public static void main(String[] args)
    {
    	//数据访问层接口
    	UserDao userDao = UserDaoFactory.getInstance().getUserDao();
    	
    	//创建用户
    	User user = new User(001,"张三","1990-04-25","北京");
    	
    	//添加用户
    	userDao.addUser(user);
    }

    如上所示,此时,我们的业务逻辑层和应用层就是纯粹的面向接口编程,如果数据访问层改变,我们甚至只需要修改配置文件给UserDaoImpl的值修改为新的即可,应用层代码完全不用变。

    小插曲:

    1. 单例模式的使用方法
        (1). 饿汉式    诸如下面代码就是一个简单的饿汉式,在类加载的同时就创建了类的实例,这也是开发中常用的方法。
public class MyClass
{
   private static MyClass instance = new MyClass();
   
   private MyClass(){
	   
   }
   
   public static MyClass getInstance(){
	   return Instance;
   }
}
        (2).懒汉式   下面是懒汉式的写法,它采用延迟加载的方式,但是同时也带来线程不安全的问题。     
public class MyClass
{
   private static MyClass instance = null;
   
   private MyClass(){
	   
   }
   
   public static MyClass getInstance(){
	  if(instance == null){
		  instance = new MyClass();
	  }
	  
	  return instance;
   }
}
     当多线程同时访问getInstance()方法时,因为该方法的内部实现不是原子操作,所以线程不安全的,加上关键字synchronized即可。

    2. 关于静态加载顺序问题          
private static MyClass instance =  new MyClass();
   private static int x = 0;
   
   private MyClass(){
	   
	   x = 100;
   }
    如上所示,当我们访问变量x的时候,它竟然是0,是的没错!在类加载的时候,首先创建instance变量,然后调用构造方法,此时x确实是100,但是往下执行,又把x赋值为0,所以最终x=0。
    在上面的工厂模式中如果按下面的顺序定义变量,那就会出错,在执行时出现空指针异常 。     
private static UserDaoFactory instance = new UserDaoFactory();
private static UserDao userDao = null;
    虽在在UserDaoFactory构造方法中得到了类的实例,但是接下来又赋值为空。

    纸上得来终觉浅,觉知此事要躬行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值