Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 链式方法设计_Java_Oop - Fatal编程技术网

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
,这很好,但不要命名该实例的类型。