我有一个CSV转换类。它的工作是捣乱价值并产生少量产出。 CSV行有大约30列。我通过不可变对象建模:
In(i1, i2, ..., iM)
OutA(a1, a2, ..., aN)
OutB(b1, b2, ..., bO)
...
OutK(k1, k2, ..., kP)
OutX(x1, x2, ..., xQ)
存在相互依赖关系:b1与a1相同,b2基于a2计算,它们组合成最终结果(OutX
)。有些计算很昂贵。
最终结果是一个看起来类似于这个简化怪物的巨大方法:
OutX method(In in) {
I1 i1 = in.getI1();
I1 i2 = in.getI2();
...
I1 iM = in.getIM();
A1 a1 = fa1(i1, i2);
A2 a2 = fa2(i2, i5, iM);
...
AN aN = ...;
OutA outA = new OutA(
a1,
a2,
...,
aN);
A1 b1 = a1;
B2 b2 = fb2(a2, i5, i13);
...
BO bO = ...;
OutB outB = new OutB(
b1,
b2,
...,
bO);
...
return new OutX(
outA,
outB,
...,
outK);
}
'很棒的是不可改变和类型检查和东西。 '这也是300行,这是CSV的每个“风味”。啊。分解只会创建主要是参数+构造函数调用的方法。
是否有非科学怪人的模式或库?
答案 0 :(得分:0)
适配器模式可能会有所帮助。每个层/ shell尽可能地委托构建最终结果。这是一个例子:
public class App {
public static void main(String[] args) {
App app = new App();
app.process();
}
private void process() {
In in = new In(1, 2, 3);
OutA a = new OutA(in);
OutB b = new OutB(a);
System.out.println(b);
}
public class In {
private final int i1;
private final int i2;
private final int i3;
public In(int i1, int i2, int i3) {
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
}
public int getI1() {
return i1;
}
public int getI2() {
return i2;
}
public int getI3() {
return i3;
}
}
public class OutA {
private final In in;
private Integer a3;
public OutA(In in) {
this.in = in;
}
public int getA1() {
return in.getI1();
}
public int getA2() {
return in.getI2() * 2;
}
public int getA3() {
if (a3 == null) {
// a3 = some expensive calculation
a3 = 1; // hold the value to avoid expensive calculation next time method is called
}
return a3;
}
}
public class OutB {
private final OutA a;
public OutB(OutA a) {
this.a = a;
}
public int getB1() {
return a.getA1();
}
public int getB2() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 4;
}
public int getB3() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 9;
}
public String toString() {
return "b1: " + getB1() + " b2: " + getB2() + " b3: " + getB3();
}
}
}
输出:b1:1 b2:5 b3:10
更新:这是一个更有趣的例子,使用工厂进行不同的计算,但仍使用相同的界面。
public class App {
public static void main(String[] args) {
App app = new App();
app.process();
}
private void process() {
In in = new In(1, 2, 3);
OutXFactory factory = new OutXFactory();
OutX resultType1 = factory.create(in, CSVType.TYPE_1);
System.out.println(resultType1);
OutX resultType2 = factory.create(in, CSVType.TYPE_2);
System.out.println(resultType2);
}
public class In {
private final int i1;
private final int i2;
private final int i3;
public In(int i1, int i2, int i3) {
this.i1 = i1;
this.i2 = i2;
this.i3 = i3;
}
public int getI1() {
return i1;
}
public int getI2() {
return i2;
}
public int getI3() {
return i3;
}
}
public enum CSVType {
TYPE_1, TYPE_2;
}
public class OutA {
private final In in;
private Integer a3;
public OutA(In in) {
this.in = in;
}
public int getA1() {
return in.getI1();
}
public int getA2() {
return in.getI2() * 2;
}
public int getA3() {
if (a3 == null) {
// a3 = some expensive calculation
a3 = 1; // hold the value to avoid expensive calculation next time method is called
}
return a3;
}
}
public class OutB {
private final OutA a;
public OutB(OutA a) {
this.a = a;
}
public int getB1() {
return a.getA1();
}
public int getB2() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 4;
}
public int getB3() {
// a.getA3() is expensive, but only the first time it's called
return a.getA3() + 9;
}
}
public interface OutX {
public int getX1();
public int getX2();
public int getX3();
}
public abstract class AbstractOutX implements OutX {
@Override
public String toString() {
return "x1: " + getX1() + " x2: " + getX2() + " x3: " + getX3();
}
}
public class OutXA extends AbstractOutX {
private final OutA a;
public OutXA(OutA a) {
this.a = a;
}
@Override
public int getX1() {
return a.getA1() + 1;
}
@Override
public int getX2() {
return a.getA2() + a.getA3() + 2;
}
@Override
public int getX3() {
return a.getA1() + a.getA2() + 3;
}
}
public class OutXAB extends AbstractOutX {
private final OutA a;
private final OutB b;
public OutXAB(OutA a, OutB b) {
this.a = a;
this.b = b;
}
@Override
public int getX1() {
return a.getA1() + b.getB1();
}
@Override
public int getX2() {
return a.getA2() * b.getB2();
}
@Override
public int getX3() {
return (int) Math.pow(a.getA3(), b.getB3());
}
}
public class OutXFactory {
public OutX create(In in, CSVType type) {
if (type == CSVType.TYPE_1) {
OutA a = new OutA(in);
return new OutXA(a);
} else {
OutA a = new OutA(in);
OutB b = new OutB(a);
return new OutXAB(a, b);
}
}
}
}