我想在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);
}
}
答案 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
}