Java FP: 伪造闭包工厂,创建域对象

最近我们想构建一个需要使用外部依赖进行计算的域对象,同时我们希望在测试的时候能够忽略这些依赖。

最开始,我们简单地在域对象中创建依赖,这使得在测试的过程中,不能随意修改依赖的值。

同样,由于外部依赖仅仅只是域对象的计算所需,并非定义域对象的可变状态,我们不应该把依赖通过构造函数传入域对象内部。

最后,我们把域对象定义成内部类,代码如下:

01 public class FooFactory {
02     private final RandomService randomService;
03  
04     public FooFactory(RandomService randomService) {
05         this.randomService = randomService;
06     }
07  
08     public Foo createFoo(String bar, int baz) {
09         return new Foo(bar, baz);
10     }
11  
12     class Foo {
13         private String bar;
14         private int baz;
15  
16         public Foo(String bar, int baz) {
17             this.bar = bar;
18             this.baz = baz;
19         }
20  
21         public int awesomeStuff() {
22             int random = randomService.random(bar, baz);
23             return random * 3;
24         }
25     }
26 }

测试这段代码的测试用例如下:

01 public class FooFactoryTest {
02  
03     @Test
04     public void createsAFoo() {
05         RandomService randomService = mock(RandomService.class);
06         when(randomService.random("bar"12)).thenReturn(13);
07         FooFactory.Foo foo = new FooFactory(randomService).createFoo("bar"12);
08         assertThat(foo.awesomeStuff(), equalTo(39));
09     }
10  
11 }

代码看似冗余,却合理地解决了测试与外部依赖的解耦问题。

参考文献

Java: Faking a closure with a factory to create a domain object

时间: 2024-10-28 03:38:46

Java FP: 伪造闭包工厂,创建域对象的相关文章

java+ 程序 子类继承父类 创建子类对象时构造方法中无显示调用父类构造方法

问题描述 java+ 程序 子类继承父类 创建子类对象时构造方法中无显示调用父类构造方法 创建子类对象时,Student s = new Student(""school""); 该构造方法中没有显示调用父类的构造方法,但还是编译成功了,该构造方法调用自身的构造函数,此构造函数中有调用父类的构造方法,执行成功的原因是什么 解决方案 不用显示调用,会自动执行父类的构造 解决方案二: 子类的构造方法中,如果没有显示调用父类的构造方法,会默认调用父类无参的构造方法.类似于

Java网络编程从入门到精通(2):创建InetAddress对象的四个静态方法

InetAddress类是Java中用于描述IP地址的类.它在java.net包中.在Java中分别用Inet4Address和Inet6Address类来描述IPv4和IPv6的地址.这两个类都是InetAddress的子类.由于InetAddress没有public的构造方法,因此,要想创建InetAddress对象,必须得依靠它的四个静态方法.InetAddress可以通过getLocalHost方法得到本机的InetAddress对象,也可以通过getByName.getAllByNam

Java网络编程从入门到精通(25):创建ServerSocket对象

ServerSocket类的构造方法有四种重载形式,它们的定义如下: public ServerSocket() throws IOException public ServerSocket(int port) throws IOException public ServerSocket(int port, int backlog) throws IOException public ServerSocket(int port, int backlog, InetAddress bindAddr

垃圾回收- 新人学java 想问一下怎么把创建的对象给清空

问题描述 新人学java 想问一下怎么把创建的对象给清空 这个我想问一下我不是已经让他等于null了吗 怎么还可以执行sayhello 如果有错误的话还麻烦告诉一下我需要创建大量相同的对象 怎么能不通过垃圾回收手动清空这个对象 解决方案 java是值传递,而不是引用传递. 如你的程序:是将内存空间中cc所指向的那个存储单元中存放的值,即c对象传送给了remove()方法中的x变量,而这个c对象也在内存空间中分配了一个存储单元,这个时候,就把c的对象传送给了这个存储单元中.此后,在remove()

js对象的创建 js对象和java对象的不同

面向对象分为   基于原型的面向对象和基于模板的面向对象. JavaScript:面向对象,基于事件的网页脚本语言. Java:基于模板的面向对象. class A {    private String name;    public void fun()    {    } } A a = new A(); a.fun();      js:基于原型的面向对象. function fun() {    var user = new Object();    user.id = 1;    u

多态-java创建锁对象的问题

问题描述 java创建锁对象的问题 在创建锁对象是都是用Lock Lock=new ReentrantLock();以多态的方式. 我想问可以使用ReentrantLock Lock=new ReentrantLock()的方式创建锁吗?_ 解决方案 Java synchronized 关于锁的对象顺序问题JAVA创建String对象的问题JAVA创建String对象问题 解决方案二: 可以啊,只不过前一个是用基类类型赋给子类实例,后者直接是个子类类型. 解决方案三: 当然可以,前者是多态,后者

浅析Java中对象的创建与对象的数据类型转换_java

Java:对象创建和初始化过程 1.Java中的数据类型    Java中有3个数据类型:基本数据类型(在Java中,boolean.byte.short.int.long.char.float.double这八种是基本数据类型).引用类型和null类型.其中,引用类型包括类类型(含数组).接口类型.     下列语句声明了一些变量: int k ; A a; //a是A数据类型的对象变量名. B b1,b2,-,b10000;// 假定B是抽象类或接口. String s;      注意:从

一个ASP创建动态对象的工厂类(类似PHP的stdClass)_ASP编程

最近整理ASP/VBScript代码,发现过去的一个ASP实现的MVC框架,可惜是个半成品,效率也成问题,不过发现里面有些我写的代码,感觉还稍稍可以拿出来见人,于是今天作此文以记之. 说是ASP,其实和VBScript也脱不了干系,VBScript语言传承于Visual Basic,VB的语法灵活度已经不尽如人意了,VBS作为其子集可想而知.神马反射.自省等先进的技术,微软在.NET中才引入.作为被抛弃的技术,也不奢望微软能够提供支持,于是顽固守旧的程序员只有绞尽脑汁的去模仿实现一些类似的功能.

一个ASP创建动态对象的工厂类(类似PHP的stdClass)

最近整理ASP/VBScript代码,发现过去的一个ASP实现的MVC框架,可惜是个半成品,效率也成问题,不过发现里面有些我写的代码,感觉还稍稍可以拿出来见人,于是今天作此文以记之. 说是ASP,其实和VBScript也脱不了干系,VBScript语言传承于Visual Basic,VB的语法灵活度已经不尽如人意了,VBS作为其子集可想而知.神马反射.自省等先进的技术,微软在.NET中才引入.作为被抛弃的技术,也不奢望微软能够提供支持,于是顽固守旧的程序员只有绞尽脑汁的去模仿实现一些类似的功能.