我有一个java网络应用程序,要求用户在4个选项之间进行选择。他们可以选择1个,全部或5个选项的任意组合。他们的选择被读入具有true / false值的Hashmap。如果选择该选项,则为true,未选中为false。根据用户选择的内容,从要处理的资源文件夹中选择不同的文件。我的问题是代码只是一堆完整的逻辑,我确信有一种更简单的方法来实现它。以下是我的问题的虚拟代码。
public class offerSelector {
public void selectOffer(Map params) {
/* Map params = Map<String, String> params = new HashMap <>();
It contains values ("internet","true),("phone","true"),("tv","true"),("cell","true")
*/
boolean option_1 = params.get("internet");
boolean option_2 = params.get("phone");
boolean option_3 = params.get("tv");
boolean option_4 = params.get("cell");
File offer = null;
if (option_1 == true && option_2 == false && option_3 == false && option_4 == false) {
offer = new File("internet_order");
}
else if(option_1 == false && option_2 == true && option_3 == false && option_4 == false) {
offer = new File("phone_order");
}
//continues like so with all possible combinations
else if(option_1 == true && option_2 == true && option_3 == true && option_4 == true) {
offer = new File("all_elements_order");
}
processOrder(offer);
}
}
答案 0 :(得分:3)
我非常喜欢将此解析推送到自定义对象(如
)public class SomeObject
{
public SomeObject(Values)
{
this.options1 = //Something
this.options2 = //Something
this.options3 = //Something
this.options4 = //Something
}
public boolean isPhone() {return option1 && option2 && option3 && !option4;}
}
然后当您使用该选项时,您可以这样做:
var x = new SomeObject(Values);
if (x.isPhone) {
// DO IS PHONE Branch
}
if (x.isFax) {
// DO IS Fax Branch
}
这样做更好,因为解析逻辑被排除在一个具有单一责任的类中。然后在你的if块中明确你所看到的内容。
其他选项是从SomeObject类返回一个Enum并使用true case / switch语句。
答案 1 :(得分:3)
有很多解决方案。例如以下内容。
定义interface Action
:
interface Action {
boolean apply(Map<String, String> params);
void perform(Map<String, String> params);
}
定义枚举操作:
enum Actions implement Action {
ONE {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
TWO {
boolean apply(Map<String, String> params) {/*implement it*/}
void perform(Map<String, String> params) {/*implement it*/}
},
;
//etc.
}
在回调方法中实现您的逻辑。显然给枚举常量正常的名字。
现在您的代码可能如下所示:
public void selectOffer(Map params) {
for (Actions a : Actions.values()) {
if (a.apply(params)) {
return a.perform(params);
}
}
}
答案 2 :(得分:2)
使用二进制表示法。每个位代表一个选项:
option4为true,option3为true,option2为false,option1为false为1100
1100 bin = 12 dec。
每个组合代表十进制数,您可以在switch
语句中使用。
我希望你理解我的意思。
答案 3 :(得分:2)
您可以尝试使用自定义对象,例如Options
:
//note that a lot of common stuff like constructors or modifiers are stripped for simplicity
class Options {
boolean internet;
boolean phone;
...
public void equals( Object other) {
return other != null &&
other.getClass().equals( getClass()) &&
other.internet == this.internet &&
other.phone == this.phone &&
...
}
public int hashCode() {
//left for your excerise, should match equals
}
}
Map<Options, File> files = ...; //create and fill
然后解析布尔参数并创建一个Options
实例,用于在地图中查找文件,例如:
Options paramOptions = new Options(/*booleans parsed from params*/);
offer = files.get( paramOptions );
答案 4 :(得分:2)
将它全部封装起来。隐藏通过另一个班级内容中的选项排列筛选的详细信息。像这样......
//controller code
Boolean internet= params.get("internet");
Boolean phone = params.get("phone");
Boolean tv= params.get("tv");
Boolean cell = params.get("cell");
File offer = FileHelper(internet, phone, tv, cell);
//end controller code ...
public class FileHelper {
private final String PHONE = "phone_order";
private final String INTERNET= "internet_order";
private final String CELL= "cell_order";
private final String TV = "tv_order";
private final String ALL = "all_elements_order";
private boolean[] options;
public FileHelper(Boolean phone, Boolean internet, Boolean cell, Boolean tv) {
options = new boolean[4];
options[0] = phone == null ? false : phone;
options[1] = internet == null ? false : internet ;
options[2] = cell== null ? false : cell;
options[3] = tv == null ? false : tv ;
}
public File getOffer() {
File f;
if ( includeAll()) f = new File(ALL);
if ( phoneOffer()) f = new File(PHONE);
if ( internetOffer()) f = new File(INTERNET);
// .... and so on
return f;
}
private boolean includeAll() {
for(boolean b : options) {
if (!b) return false;
}
return true;
}
private boolean internetOffer() {
return getSingleOption() == 1;
}
private boolean phoneOffer() {
return getSingleOption() == 0;
}
private int getSingleOption() {
int i = -1;
for(int j; j =0; j++) {
if(options[j]) {
if ( i >= 0) {
return -1; //user has selected > 1 option
} else {
i = j;
}
}
}
return i;
}
}
我猜测boolean []不会受欢迎,但我认为拥有这样的结构可以让您轻松确定用户标记为真的选项数量,从您的问题看起来就像是'我想知道。
答案 5 :(得分:1)
很抱歉没有评论的声誉, 首先你可以使用开关:http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html,对于像这样的代码来说容易得多,也许对于组织你可以使用从这个开始的另一个函数(只记得把这些字符串放在一起)