避免if语句

Ori*_*Ori 39 oop if-statement

我今天正在考虑面向对象的设计,我想知道你是否应该避免if语句.我的想法是,在任何需要if语句的情况下,您只需创建两个实现相同方法的对象.这两个方法实现只是原始if语句的两个可能的分支.

我意识到这似乎是极端的,但似乎你可以尝试在某种程度上争论它.有什么想法吗?

编辑

哇,没多久.我想这太极端了.是否有可能说,在OOP下你应该期望更少的陈述?

第二次编辑

那么:一个根据其属性确定方法实现的对象.也就是说,您可以someMethod()通过两种方式实现并指定一些限制.在任何时候,对象都将根据其属性路由到正确的方法实现.所以在if(x > 5)只有两个依赖x属性的方法的情况下

van*_*nce 44

我可以告诉你一件事.无论人们怎么说,考虑简化和消除不必要的分支都是您成为软件开发人员的标志.分支错误,测试,维护,错误率较高等原因有很多.这是我在面试人员时所寻求的事情之一,也是他们作为开发人员成熟程度的绝佳指标.我鼓励您继续尝试,通过使用更少的条件来简化代码和设计.当我执行此切换时,我发现调试代码的时间要少得多,它只是起作用,然后当我不得不改变某些内容时,由于大多数代码都是顺序的,所以更改非常容易.无论别人怎么说,我都鼓励你100%继续做你正在做的事情.请记住,大多数开发人员的工作和思考程度要低得多,并且只遵循规则.如此出色的工作.


Ste*_*all 13

解释如何在没有if语句或三元逻辑的情况下实现以下内容:

if ( x < 5 ) {
   x = 0
} else {
   print x;
}
Run Code Online (Sandbox Code Playgroud)

  • 总是有可能提出一种用一种语言很容易但在另一种语言中很难的人为例子.解释如何在C#中实现"(~RεR∘.×R)/ R←1↓⍳R"(实际有用的算法) - 这是否证明APL在实际程序中优于C#?什么时候你最后一次在程序中有这样的逻辑("零或打印" - 真的吗?)? (12认同)
  • 在某些语言中,您可以通过方法重载来完成.BAM! (6认同)
  • @iftrue,我演示的功能map-reduce-ish方法也是一种方法.不讨厌,它被世界各地的功能人员使用. (3认同)
  • @ e-满足iftrue提出的代码根据条件做了2个不相关的事情.是的,不相关的概念分为不同的类.更容易测试,更容易掌握,更容易替代替代品. (3认同)
  • ((x> = 5)&&!(x = 0))|| (打印x,1) (2认同)
  • 打印x; 是UI代码,应该从业务逻辑x = 0中分离出来; 如果将更改值的代码移动到一组类中,然后将代码打印到是否打印到一组类中,那么您将不会有任何IF语句.这是一个争论的唯一原因是因为你正在结合关注点. (2认同)

Fra*_*man 10

是的,通常可以通过多态性简化复杂的条件.但它一直没用.去阅读福勒的重构书来了解何时.

http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html

  • 福勒定律:当你深入了解面向对象编程时,你会发现马丁福勒多年前发表过这个想法......来自http://nomorehacks.wordpress.com/2009/08/25/fowlers-law/ (5认同)

Daw*_*uss 8

完全消除if语句是不现实的,我不认为这是Ori的建议.但它们通常可以使用多态来替换.(许多转换语句也是如此).

Francesco Cirillo启动了Anti-If运动,以提高对这一问题的认识.他说:

了解如何使用对象可以让开发人员根据类型消除IF,这些IF通常会损害软件的灵活性和发展能力.

您或您的团队也可以加入该广告系列.


e-s*_*tis 6

我的一位老师曾经这么说过.我倾向于认为那些对这种事情如此教条的人通常不会以谋生为目的.


Mic*_*own 5

看一下Anti-If Campaign这个想法不是要在你的应用程序中用策略或状态模式替换每一个.这个想法是,当你有一个复杂的分支逻辑,特别是基于枚举的东西时,你应该考虑重构战略模式.

在这种情况下,您可以使用Factory删除if all.这是一个相对简单的例子.当然,正如我在一个实际案例中所说的那样,你的策略中的逻辑会比打印出"我活跃"更复杂一些.

public enum WorkflowState
{
  Ready,
  Active,
  Complete
}

public interface IWorkflowStrategy
{
  void Execute();
}

public class ActiveWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Active");
  }
}

public class ReadyWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Ready");
  }
}

public class CompleteWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Complete");
  }
}

public class WorkflowStrategyFactory
{
  private static Dictionary<WorkflowState, IWorkflowStrategy> _Strategies= 
    new Dictionary<WorkflowState, IWorkflowStrategy>();
  public WorkflowStrategyFactory()
  {
    _Strategies[WorkflowState.Ready]=new ReadyWorkflowStrategy();
    _Strategies[WorkflowState.Active]= new ActiveWorkflowStrategy();
    _Strategies[WorkflowState.Complete = new CompleteWorkflowStrategy();
  }
  public IWorkflowStrategy GetStrategy(WorkflowState state)
  {
    return _Strategies[state];
  }
}

public class Workflow
{
    public Workflow(WorkflowState state)
    {
        CurrentState = state;
    }
    public WorkflowState CurrentState { get; set; }
}

public class WorkflowEngine
{
    static void Main(string[] args)
    {
        var factory = new WorkflowStrategyFactory();
        var workflows =
            new List<Workflow>
                {
                    new Workflow(WorkflowState.Active),
                    new Workflow(WorkflowState.Complete),
                    new Workflow(WorkflowState.Ready)
                };
        foreach (var workflow in workflows)
        {
            factory.GetStrategy(workflow.CurrentState).
                Execute();
        }
    }
}   
Run Code Online (Sandbox Code Playgroud)


小智 5

避免陈述:有很多方法可以做,其中一种方法如下:

int i=0;
if(i==1)
{
//Statement1
}

if(i==2)
{
//Statement2
}

if(i==3)
{
//Statement3
}

if(i==4)
{
//Statement4
}
Run Code Online (Sandbox Code Playgroud)

使用Dictionary和delegate:

delegate void GetStatement ();

Dictionary<int,GetStatement > valuesDic=new Dictionary<int,GetStatement >();

void GetStatement1()
{
//Statement1
}
void GetStatement2()
{
//Statement2
}
void GetStatement3()
{
//Statement3
}


void GetStatement4()
{
//Statement4
}

void LoadValues()
{
valuesDic.Add(1,GetStatement1);
valuesDic.Add(2,GetStatement2);
valuesDic.Add(3,GetStatement3);
valuesDic.Add(4,GetStatement4);

}
Run Code Online (Sandbox Code Playgroud)

替换If语句:

int i=0;
valuesDic[i].Invoke();
Run Code Online (Sandbox Code Playgroud)