Java 链式方法设计
我编写了一个简单的类来演示链式方法设计:Java 链式方法设计,java,oop,Java,Oop,我编写了一个简单的类来演示链式方法设计: public class Cal { private Cal(){} private boolean isCheckArguments = false; public static Cal useAbs() { return new Cal(){ @Override int check(int i) { return Math.abs(i);
public class Cal {
private Cal(){}
private boolean isCheckArguments = false;
public static Cal useAbs() {
return new Cal(){
@Override int check(int i) {
return Math.abs(i);
}};
}
public static Cal useNormal() {
return new Cal();
}
public Cal checkArguments() {
isCheckArguments =true;
return this;
}
int check(int i){ return i;}
public int plus(int i, int j) {
if(isCheckArguments && i<j){
throw new IllegalArgumentException("i<j!");
}
return check(i+j);
}
}
我的问题是:这是一个合理的设计吗?与:intplus(inta,intb,boolean useab,boolean checkArguments)
。谢谢 这叫做a,在我看来很合理
我建议更改类的名称:Calc
显然是一个计算器,而不是Cal
(可以是日历而不是计算器)。IMHO,这种“链接”方法在Java中并不常用,除非是构建器或本质上是构建器的东西
您在这里描述的实际上是一个计算器生成器
您可能应该有一个CalculatorBuilder类,您可以实例化该类,设置多个内容(例如,useAbs、checkArguments等),并最终调用“build”。Build将返回一个计算器,该计算器不知道它是如何生成的,只知道它初始化时的状态
另外,我个人不喜欢混合构建器风格逻辑(例如,“useAbs”)和影响底层对象状态的东西(例如checkArguments)的设计。我要说挑一个。生成一个默认计算器并在以后设置所有内容,或者让一个生成器设置所有内容,然后创建功能和行为无法更改的实例。听起来您需要一个流畅的界面来构建服务类。番石榴也有类似的作用。你可以这样做:
public interface Cal {
int plus(int a, int b);
}
public class CalBuilder {
class InternalCal implements Cal {
boolean useAbs;
boolean checkArgs;
public int plus(int a, int b) {
if(checkArgs) {
// blah, blah blah
}
if(useAbs) {
// doodle bug, doodle darn
}
return a+b; // whatevs
}
}
boolean absSet=false;
InternalCal holder=new InternalCal();
public CalBuilder useNormal() {
if(absSet) { throw new IllegalArgumentException(); } // already called
holder.useAbs=false;
absSet=true;
return this;
}
public CalBuilder useAbs() {
if(absSet) { throw new IllegalArgumentException(); } // already called
holder.useAbs=false;
absSet=true;
return this;
}
public CalBuilder checkArguments() {
if(holder.checkArgs) { throw new IllegalArgumentException(); }
holder.checkArgs=true;
return this;
}
public Cal build() {
return holder;
}
}
Cal cal=new CalBuilder().useAbs().checkArguments().build();
int sum=cal.plus(1,2);
用法如下所示:
public interface Cal {
int plus(int a, int b);
}
public class CalBuilder {
class InternalCal implements Cal {
boolean useAbs;
boolean checkArgs;
public int plus(int a, int b) {
if(checkArgs) {
// blah, blah blah
}
if(useAbs) {
// doodle bug, doodle darn
}
return a+b; // whatevs
}
}
boolean absSet=false;
InternalCal holder=new InternalCal();
public CalBuilder useNormal() {
if(absSet) { throw new IllegalArgumentException(); } // already called
holder.useAbs=false;
absSet=true;
return this;
}
public CalBuilder useAbs() {
if(absSet) { throw new IllegalArgumentException(); } // already called
holder.useAbs=false;
absSet=true;
return this;
}
public CalBuilder checkArguments() {
if(holder.checkArgs) { throw new IllegalArgumentException(); }
holder.checkArgs=true;
return this;
}
public Cal build() {
return holder;
}
}
Cal cal=new CalBuilder().useAbs().checkArguments().build();
int sum=cal.plus(1,2);
最好的设计是简单的设计。您正在做的是混淆代码。读取和修复错误比“plus(a、b、useAbs、checkArguments)”更难。此外,在useNormal中,您返回的对象与“new Cal()”的对象相同,因为您重写了check(int)方法,并使用super.check(int)返回父级实现。生成器模式通常用于构造不可变对象和/或用许多(可能是可选的)参数替换构造函数。我在这里看不到这两种情况。我不同意——至少从他的例子来看,似乎每个计算器都以完全不同的方式运行,让一个计算器改变它的状态是没有好处的。在post中,new Cal()以useNormal返回。非常确定
CalBuilder
应该是一个static
类,然后它将被这样调用:Cal Cal=new Cal.Builder()…
当然,您可以用很多方法来实现它。然而,你通常不希望一个构建器是静态的,因为那样你就不能从多个线程调用它,而且你会有事情与其他线程的状态发生冲突。我想你误解了我的意思。生成器对象将不是静态的,builder
类将是静态的。看(和/或)是的,我误解了你的意思<代码>计算器会更好。完整的单词通常更容易阅读。如果您想命名它的一个实例calc
,这很好,但不要命名该实例的类型。