一种设计模式方法,用于返回布尔值和字符串

时间:2013-11-27 19:19:23

标签: java design-patterns

我想在java中编写一个方法,它接收一个对象数组,检查一些兼容性并返回一个布尔值true如果全部满足,否则返回一个包含消息的字符串,告知用户为什么某些兼容性不能见面。 我想出了我的问题的简化版本如下:

假设您想要比较汽车,并且为了比较有意义,您需要确保所有颜色相同,颜色相同,颜色相同。

所以我想从这个方法得到的是两个:

1-是否兼容? (boolean using return)

如果没有,为什么?所以告知用户原因(String using throw)

最佳设计模式是什么?

以下是实现它的一种方法:

boolean areCarsCompatible(Car [] cars) throws CarException {
String errorMessage = "";
   for(Car car:cars){
    if (cars done have same color) errorMessage +="Cars dont have same color";
   }

   for(Car car:cars){
    if (cars done have same make) errorMessage +="Cars dont have same make";
   }

   for(Car car:cars){
    if (cars are not all of same class) errorMessage +="cars are not all of same class";
   }

   if (errorMessage.equals("")){
    return true 
   } else {
       throw new  CarException (errorMessage);
   }

 }

6 个答案:

答案 0 :(得分:2)

  

返回布尔值和字符串

虽然您可以在其他(动态)编程语言中执行此操作,但强烈建议您不要在Java中设计这样的方法。在Java中,类型是静态检查和严格的,你只是不能从同一个方法返回两个不同的类型,并且当你想要返回一个字符串时抛出异常,这只是一个丑陋的黑客。

另一个问题是抛出异常并带有表示错误的消息,这是一种非常常见的做法,并且在语言的良好实践中。但请注意,您不会“返回布尔值和字符串”,例外是用于错误处理。

答案 1 :(得分:2)

您的方法可以是void并在出现任何问题时抛出异常。它不需要返回布尔值。调用者应该假设如果没有抛出异常那么一切都OK。这正是设计使用异常的方式。

我会重命名方法:

void checkCompatibilityOf(Car... cars) throws IncompatibleCarsException


替代方法:控制倒置

不是从方法中返回值,而是可以让方法回答其答案。 E.g。

interface CompatibilityListener {

    void onSuccess();

    void onFailure(String message); 
}

这将避免需要布尔返回值,并且不需要例外。

您可以进一步提取构建错误消息的逻辑:

interface DifferenceListener {

    void onDifferentColor(Car car1, Car car2);

    void onDifferentMake(Car car1, Car car2);

    //etc.
}

这个方法:

public void checkCompatibilityOf(DifferenceListener listener, Cars... cars) {

    for (Car car: cars) {
       if (...) {
           listener.onDifferentColor(car1, car2);
       }
       if (...) {
           listener.onDifferentMake(car1, car2);
       }
       // etc.    
    }
}

在某些情况下,控制反转可能是一种强有力的方法,但正如Vidya所说(在评论中),它可能在你的情况下过度工程化了!

答案 2 :(得分:1)

您可以使用JAVA完成所有您想做的事情。您可以创建自己的类,以获取具有您喜欢的任何包含值的对象。见下文:

import java.math.BigInteger;
import java.util.Date;


public class BoolVariable {

private static BoolVariable instance;
public static BoolVariable BOOLVARIABLE = getInstance();
private boolean bool;
private char c;
private String s;
private int i;
private double d;
private float f;
private BigInteger bi;
private Date date;

private static BoolVariable getInstance() {
    if (instance == null) {
        instance = new BoolVariable();
    }
    return instance;
}

private BoolVariable() {
}

public BoolVariable(boolean bool, char c) {
    this.bool = bool;
    this.c = c;
}

public BoolVariable(boolean bool, String s) {
    this.bool = bool;
    this.s = s;
}

public BoolVariable(boolean bool, int i) {
    this.bool = bool;
    this.i = i;
}

public BoolVariable(boolean bool, double d) {
    this.bool = bool;
    this.d = d;
}

public BoolVariable(boolean bool, float f) {
    this.bool = bool;
    this.f = f;
}

public BoolVariable(boolean bool, BigInteger bi) {
    this.bool = bool;
    this.bi = bi;
}

public BoolVariable(boolean bool, Date date) {
    this.bool = bool;
    this.date = date;
}



public boolean getBool() {
    return bool;
}

public char getC() {
    return c;
}

public String getS() {
    return s;
}

public int getI() {
    return i;
}

public double getD() {
    return d;
}

public float getF() {
    return f;
}

public BigInteger getBi() {
    return bi;
}

public Date getDate() {
    return date;
}

public void setBool(boolean bool) {
    this.bool = bool;
}

public void setC(char c) {
    this.c = c;
}

public void setS(String s) {
    this.s = s;
}

public void setI(int i) {
    this.i = i;
}

public void setD(double d) {
    this.d = d;
}

public void setF(float f) {
    this.f = f;
}

public void setBi(BigInteger bi) {
    this.bi = bi;
}

public void setDate(Date date) {
    this.date = date;
}

public BoolVariable create(boolean bool, char c){
    return new BoolVariable(bool, c);
}
public BoolVariable create(boolean bool, String s){
    return new BoolVariable(bool, s);
}
public BoolVariable create(boolean bool, int i){
    return new BoolVariable(bool, i);
}
public BoolVariable create(boolean bool, double d){
    return new BoolVariable(bool, d);
}
public BoolVariable create(boolean bool, float f){
    return new BoolVariable(bool, f);
}
public BoolVariable create(boolean bool, BigInteger bi){
    return new BoolVariable(bool, bi);
}
public BoolVariable create(boolean bool, Date date){
    return new BoolVariable(bool, date);
}

@Override
public String toString() {
    return "BoolVariable{" + "bool=" + bool + ", c=" + c + ", s=" 
            + s + ", i=" + i + ", d=" + d + ", f=" + f + ", bi=" 
            + bi + ", date=" + date + '}';
}

}

您可以在想要获取双变量的任何例程中调用此类,如下所示:

BoolVariable bv = BOOLVARIABLE.create(true, "HERE IS YOUR VARIABLE LIKE INTEGER, STRING ETC");

因此,您可以获得bv.getBool();之类的任何值

答案 3 :(得分:0)

一个想法是始终返回布尔值,但如果不满足条件,则抛出描述问题的RuntimeException风格。这种方法的调用者应该处理它。

答案 4 :(得分:0)

您还可以创建负责检查汽车的班级。

public class CarVerificator {

    private StringBuilder errorMessage = new StringBuilder();

    /* if false returned - check error message */
    public boolean checkCompatibility(Cars[] cars) {
        boolean checkColorRun = true;
        boolean checkMakeRun = true;
        boolean checkClassRun = true;

        for (Car car : cars) {
            checkColorRun && checkColorRun = checkColor(car);
            checkMakeRun && checkMakeRun = checkMake(car);
            checkClassRun && checkClassRun = checkClass(car);
            if (!checkColorRun && !checkClassRun && !checkMakeRun) break;
        }
        return getResult();
    }

    public String getErrorMessage() {
        return errorMessage.toString();
    }

    private boolean checkColor(Car car) { /* check and log to errorMessage */ }

    private boolean checkMake(Car car) { /* check and log to errorMessage */ }

    private boolean checkClass(Car car) { /* check and log to errorMessage */ }

    private boolean getResult() {
        return checkColorRun && checkMakeRun && checkClassRun;
    }

}

答案 5 :(得分:0)

这里有很多要解决的问题。

首先,您正在寻求设计,方法,算法等,但请不要将其称为设计模式。该术语具有非常特殊的含义。

好的,除了挑剔语义之外,由于几个原因,你的方法有点尴尬。首先,boolean有点无用,因为你不关心“虚假”。要么一切正常,要么得到某种消息。值false对您没有任何价值。

另一个令人尴尬的原因是@OscarLopez建议的那样。例如,在Java中没有简洁的方法来返回多类型值。

我会说,如果您要抛出异常,那么CarException正在接近正确的方法 - 如果它似乎是已检查异常。我非常不同意@cherouvim(尽管我没有投票)它应该是RuntimeException。您希望调用者了解它并且必须处理它。

至于我自己的解决方案建议,我有两个:

1)保持Car进入馆藏所需标准的一些概念。如果不符合这些条件,则不要向集合中添加Car。换句话说,首先要防止问题的发生,从而解决问题。

2)使用Enum s。

public enum CarFeedback {
        ALL_SAME, DIFFERENT_COLORS, DIFFERENT_MAKES, DIFFERENT_CLASSES 
}

public CarFeedback checkCars(List<Car> cars) {
      //Do checks 

      return ALL_SAME; //or whichever enum value is appropriate

}