我一直在编程很多时间。通常我用PHP,ASP.net,Java,JavaScript等语言编程。在所有语言中,我必须使用很多if else语句。就像值= 10然后......如果我查看我的代码然后我发现很多if条件。所以我想尽量减少它们但不确定。
有一点是使用了稍微最小化的类,但它们仍然更多......
喜欢task,cat,sec和type:
if task = 'add' then
if cat = "animal" then
if sec = "man" then
if type = "male" then
'do the following stuffs
else
'do the following stuffs
end if
elseif sec = "horse" then
if type = "run"
'do the following stuffs
else
'do the following stuffs
end if
elseif....
end if
elseif cat = "plant" then
if sec = "land" then
if type="tree" then
'do the following stuffs
elseif type = "grass" then..
'do the following stuffs
elseif...
end if
elseif sec = "water" then
...
...
...
更多n继续n继续
所以我想知道如何最小化它们并编写一些有效的代码?
很抱歉最近通知任务,cat,sec和type可能有很多值。我的if语句嵌套嵌套。
更多解释我的代码看起来也像:
http://thedailywtf.com/Articles/Coding-Like-the-Tour-de-France.aspx
答案 0 :(得分:14)
许多if..else
语句通常是Polymorphism未被使用的症状。
答案 1 :(得分:4)
它被称为'箭头反模式' 下面介绍了处理它的一些方法:http://c2.com/cgi/wiki?ArrowAntiPattern
您迁移的方法之一是重构嵌套级别的代码以分隔函数,如
if cat = "animal" then
functionForAnimal();
elseif cat = "plant" then
functionForPlant();
elseif...
function functionForAnimal()
if sec = "man" then
functionForMan();
elseif sec = "horse" then
functionForHorse();
elseif...
etc...
这会将代码拆分为更小的片段,这些片段更易于维护,并且可能重复使用。
答案 2 :(得分:4)
假设您总是进行相等比较,并比较所有四个字段,那么简单的数据驱动方法就非常实用。您需要做的就是构建一个从(task,cat,sec,type)到要调用的函数的映射:
handlers = {
('add', 'animal', 'man', 'male'): add_man_func,
('add', 'animal', 'horse', 'run'): run_horse_func,
# ...
}
handler = handlers[(task, cat, sec, type)]
handler(some_args)
答案 3 :(得分:2)
Polymorphism可能很有用,但任务在概念上是相同的。有时很难找到自然的类结构,像state pattern或strategy pattern这样的方法可能更合适。
答案 4 :(得分:2)
您描述了一个包含4个传入参数的矩阵 - task, cat, sec, type
和一个传出 - stuff
。所以你必须对它进行编码。
例如,XML map和XPath查询,即String.Format("task[@value={0}]/cat[@value={1}]/sec[@value={2}]/type[@value={3}]", "add", "animal", "man", "male")
,但此方法指向数据,而不是方法委托。
另一种方式:
void DoStuffA() { }
void DoStuffB() { }
var arr = new[]
{
new { Task = "Add", Cat = "Animal", Sec = "Man", Type = "Male", Method = (Action)DoStuffA },
new { Task = "Add", Cat = "Plant", Sec = "Land", Type = "Tree", Method = (Action)DoStuffB },
// etc..
};
var action = arr.FirstOrDefault(i =>
i.Task == "Add" &&
i.Cat == "Animal" &&
i.Type == "Male").Method;
action();
此外,您不能使用匿名成员,而是声明一个类,用XML描述您的变体,并将它们从XML反序列化为多个类实例。
答案 5 :(得分:1)
我认为您的设计存在一些根本性缺陷。我不知道你试图用这个代码解决什么问题,但这种代码在面向对象的语言中应该是非常罕见的。你的代码对我来说似乎也有点不合逻辑,因为,例如,变量类型在第一次使用(男性)时意味着性别,然后它意味着一个动作(运行)。你注意到了吗?
无论如何,如果你确实使用Java(或任何类),你需要的是抽象。接下来,将所有逻辑移到对象上 - 不要在一个怪异的例程中处理它。这样想:我的对象知道如何发挥自己的作用。
实际上在这种情况下给出好的建议有点困难,我怀疑你的问题在你的应用程序中有一些高级别的来源,这个案例代码只是一个症状。尝试重新设计你的程序以使用面向对象的方法,也许你会想到一个更好的解决方案。
如果您不确定多态,抽象和其他OO术语的含义,您需要阅读此内容。
答案 6 :(得分:0)
如果每个变量的选择都是有限的,那么你甚至可以使用带有OR运算的位字段等技巧。
示例:
// give each field a byte so that each can have 256 possible values
#define TASK_ADD 0x01
#define TASK_SUB 0x02
...
#define CAT_ANIMAL 0x01
...
#define SEC_BOY 0x03
#define SEC_MAN 0x04
...
#define TYPE_FEMALE 0x01
#define TYPE_MALE 0x02
...
if ((task << 24 | cat << 16 | sec << 8 | type) == 0x01010402) {
// do stuff
}
答案 7 :(得分:0)
在某个地方,您需要使用if-elses检查条件,以确保您做正确的事情。如果你不想填充一个子
,你可以创建新的潜艇Sub AddAnimalManMale()
If task = 'add' And cat = 'animal' And sec = 'man' And type = 'male' Then
'perform the add animal man male action'
End If
End Sub
Sub AddAnimalHorseRun()
If task = 'add' And cat = 'animal' And sec = 'horse' And type = 'run' Then
'perform the add animal horse run action'
End If
End Sub
然后在你的主要子
...
Call AddAnimalManMale()
Call AddAnimalHorseRun()
...
答案 8 :(得分:0)
打破代码是游戏的全部内容。
从历史上你会做(并且有好的,或者至少是稳定的代码,并且仍然存在所有这些代码)
正如你现在所做的那样,在巨大的功能中单片,有很多评论
将其拆分为定义良好且命名良好的函数
命名函数对于复杂的东西来说很棘手,而且如果你继续传递对大结构的引用,那么对象是一个自然而然的发明(但是,一旦你进入对象的方式,那么做任何事情并通过重用是有意义的面向代码对象的模式出现......)
识别模式的方式类似于为函数赋予好名字(此外,您可以获得自然有用的方法,这可能是巨大的胜利)。