Java工厂模式解耦合的例子

最终项目路径如下:
在这里插入图片描述

第一个例子

假设有如下接口,

package service;

public interface Notice {
	public void work(String message);
}

实现类如下,

package service;

public class NoticeImpl implements Notice {

	@Override
	public void work(String message) {
		// TODO Auto-generated method stub
		System.out.println(message);
	}

}

单元测试类编写如下,

package iTest;

import org.junit.Test;

import demo.Factory;
import service.Notice;
import service.NoticeImpl;

public class TestRun {
	@Test
	public void helloWorld() {
		Notice notice = new NoticeImpl();
		System.out.println("hello world! " + notice);
	}
	
	@Test
	public void work() {
		Notice notice = new NoticeImpl();
		notice.work("Hello Work");
	}
}

此时,如果我觉得NoticeImpl实现不满意,想替换成NoticeNewImpl,这时测试组(或者调用者)需要重写代码(e.g. 将代码中所有的NoticeImpl替换成NoticeNewImpl)进行重编译等,存在冗余。

第二个例子

使用工厂模式,

package demo;

import service.Notice;
import service.NoticeImpl;

public class Factory {
	public static Notice getNoticeInstance(){
		return new NoticeImpl();
	}
}

单元测试类改为,

package iTest;

import org.junit.Test;

import demo.Factory;
import service.Notice;

public class TestRun {
	@Test
	public void helloWorld() {
		Notice notice = Factory.getNoticeInstance();
		System.out.println("hello world! " + notice);
	}
	
	@Test
	public void work() {
		Notice notice = Factory.getNoticeInstance();
		notice.work("Hello Work");
	}
}

此时,仅需改动的代码只有1处。但替换NoticeNewImpl时还是需要重编译工厂类,有点麻烦。

第三个例子

借用配置文件applicationContext.property和类反射机制(面试题),工厂类改写如下(现在静态代码块加载env,面试题),

package demo;

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

import service.Notice;

public class Factory {	
	private static Properties env = new Properties();

	static {
		try (InputStream inputStream = Factory.class.getResourceAsStream("/resource/applicationContext.properties")) {
			env.load(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static Notice getNoticeInstance(){
		Notice one = null;

		try {
			Class clazz = Class.forName(env.getProperty("Notice"));
			one = (Notice) clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return one;
		}
	}
}

配置文件applicationContext.property内容如下,

Notice = service.NoticeImpl

现在想替换NoticeNewImpl时仅需改写配置文件。此时,还有额外问题,即工厂类需要实现多个getXxxInstance方法,代码存在冗余。

第四个例子

升级为通用工厂,代码改写如下,

package demo;

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

import service.Notice;

public class Factory {
	private static Properties env = new Properties();

	static {
		try (InputStream inputStream = Factory.class.getResourceAsStream("/resource/applicationContext.properties")) {
			env.load(inputStream);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static Object getOneInstance(String interfaceName) {
		Object one = null;

		try {
			Class clazz = Class.forName(env.getProperty(interfaceName));
			one = clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return one;
		}
	}
}

单元测试类(调用者代码)改写如下,

package iTest;

import org.junit.Test;

import demo.Factory;
import service.Notice;

public class TestRun {
	@Test
	public void helloWorld() {
		Notice notice = (Notice) Factory.getOneInstance("Notice");
		System.out.println("hello world! " + notice);
	}
	
	@Test
	public void work() {
		Notice notice = (Notice) Factory.getOneInstance("Notice");
		notice.work("Hello Work");
	}

}

配置文件applicationContext.property内容依旧如下,

Notice = service.NoticeImpl

OK,现在代码无耦合无冗余。

Reference

孙哥说Spring5(2020版) 6月30日 已更新 ~学不会Spring? 因为你没找对人(b站视频)
java的单元测试和集成spring单元测试

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值