Java工厂模式解耦合的例子

    技术2022-07-11  86

    目录

    第一个例子第二个例子第三个例子第四个例子Reference

    最终项目路径如下:

    第一个例子

    假设有如下接口,

    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单元测试

    Processed: 0.027, SQL: 9