停止使用If-Else语句

重点 (Top highlight)

应用的设计模式:状态 (APPLIED DESIGN PATTERNS: STATE)

You’ve watched countless tutorials using If-Else statements. You’ve probably also read programming books promoting the use of If-Else as the de facto branching technique.

您已经看过使用If-Else语句的无数教程。 您可能还读过编程书籍,以促进将If-Else用作事实上的分支技术。

It’s perhaps even your default mode to use If-Else. But, let’s put an end to that right now, by replacing If-Else with the state objects.

使用If-Else甚至可能是您的默认模式。 但是,让我们现在结束这一点 ,将If-Else替换为状态对象。

Note that you’d use this approach if you’re writing a class with methods that need its implementations to be changed depending on the current state. You’d apply another approach if you’re not dealing with an object’s changing state.

请注意,如果要编写一个类的方法需要根据当前状态更改其实现,则可以使用此方法。 如果您不处理对象的变化状态,则可以采用另一种方法。

Even if you’ve heard about the state pattern, you might wonder how it is implemented in production-ready code.

即使您听说过状态模式,也可能想知道如何在生产就绪型代码中实现状态模式。

For anyone who’s still in the dark, here’s a very brief introduction.

对于仍在黑暗中的任何人,这里有一个非常简短的介绍。

You’ll increase complexity with any new conditional requirement implemented using If-Else.

使用If-Else实施的任何新的条件要求都会增加复杂性。

Applying the state pattern, you simply alter an objects behavior using specialized state objects instead of If-Else statements.

应用状态模式,您只需使用专用状态对象而不是If-Else语句来更改对象行为。

Gone are the days with code looking like this below.

看起来像下面这样的代码的日子已经一去不复返了。

Poor if-else statements
Warning: PTSD trigger — also, hope you caught the logical error in here (other than the whole thing being a mess)
警告:PTSD触发器-另外,希望您在这里捕获了逻辑错误(除了整个事情都一团糟)

You’ve certainly written more complicated branching before. I have for sure some years ago.

您肯定已经写过更复杂的分支。 我肯定在几年前。

The branching logic above isn’t even very complex — but try adding new conditions and you’ll see the thing explode.

上面的分支逻辑甚至还不是很复杂-但是尝试添加新条件,您会发现事情爆炸了。

Also, if you think creating new classes instead of simply using branching statements sounds annoying, wait till you see it in action. It’s concise and elegant.

另外,如果您认为创建新类而不是简单地使用分支语句听起来很烦,请等到实际操作起来再做。 简洁而优雅。

Even better, it’ll make your codebase more SOLID, except for the “D” part tho.

更好的是,除了“ D”部分之外,它还将使您的代码库更加扎实。

“好吧,我坚信If-Else是邪恶的,现在向我展示如何避免混乱的分支代码” (“Okay, I’m convinced If-Else is evil, now show me how to avoid messy branching code”)

We’ll be looking at how I replace If-Else branching in production-ready code. It’s a made-up example, but the approach is the same I’ve used in codebases for large clients.

我们将研究如何在生产就绪代码中替换If-Else分支。 这是一个虚构的示例,但是该方法与我在大型客户端的代码库中使用的方法相同。

Let’s create a very simple Booking class, that has a few states. It’ll also have two public methods:Accept() and Cancel().

让我们创建一个具有几个状态的非常简单的Booking类。 它还有两个公共方法: Accept() and Cancel()

I’ve drawn a diagram to the best of my abilities that displays the different states a booking may be in.

我已尽力绘制了一个图表,显示了预订可能处于的不同状态。

Image for post

Refactoring branching logic out of our code is a three step process:

从我们的代码中重构分支逻辑是一个三步过程:

  1. Create an abstract base state class

    创建一个抽象的基态类
  2. Implement each state as a separate class inheriting from base state

    将每个状态实现为继承自基本状态的单独类
  3. Let the Booking` class have a private or internal method that takes the state base class as a parameter

    Booking `类具有取状态基类为参数的私有或内部方法

演示时间 (Demo time)

First, we need a base state class that all states will inherit from.

首先 ,我们需要一个将继承所有状态的基态类。

Image for post

Notice how this base class also has the two methods, Accept and Cancel — although here they are marked as internal.

请注意,该基类还具有两个方法Accept和Cancel,尽管此处将它们标记为内部。

Additionally, the base state has a “special” EnterState(Booking booking) method. This is called whenever a new state is assigned to the booking object.

此外,基本状态具有“特殊” EnterState(Booking booking)方法。 每当将新状态分配给预订对象时,就会调用此方法。

Secondly, we’re making separate classes for each state we want to represent.

其次 ,我们为要表示的每个状态创建单独的类。

Image for post

Notice how each class represents a state as described in the beautiful diagram above. Also, the CancelledState won’t allow our booking to transition to a new state. This class is very similar in spirit to the Null Object Pattern.

请注意,如上图所示,每个类如何表示一个状态。 此外,CancelledState不允许我们的预订过渡到新状态。 此类在本质上与Null对象模式非常相似。

Finally, the booking class itself.

最后 ,预订类本身。

Image for post

See how the booking class is simply delegating the implementation of Accept and Cancel to its state object?

看到预订类如何简单地将Accept和Cancel的实现委派给其状态对象?

Doing this allows us to remove much of the conditional logic, and lets each state only focus on what’s important to itself — the current state also has the opportunity to transition the booking to a new state.

这样做使我们可以删除许多条件逻辑,并让每个州仅专注于对自己重要的事情-当前状态也有机会将预订过渡到新状态。

如何处理新的条件功能? (How to deal with new conditional features?)

If the new feature would normally have been implemented using some conditional checking, you can now just create a new state class.

如果通常可以使用某些条件检查来实现新功能,则现在只需创建一个新的状态类即可。

It’s as simple as that. You’ll no longer have to deal with unwieldy if-else statements.

就这么简单。 您将不再需要处理笨拙的if-else语句。

如何将状态对象保留在数据库中? (How do I persist the state object in a database?)

You don’t.

你不知道

The state object is not important when saving an object to e.g. an SQL or NoSQL database. Only knowing the object’s state and how it should be mapped to a column is important.

将对象保存到例如SQL或NoSQL数据库时,状态对象并不重要。 仅了解对象的状态以及应如何将其映射到列很重要。

You can map a state to a friendly type name, an enum or an integer. Whatever you’re comfortable with, as long as you have some way of converting the saved value back into a state object.

您可以将状态映射到友好类型名称,枚举或整数。 只要您满意,只要有某种方法可以将保存的值转换回状态对象。

但是您仍在使用IF吗? (But you’re still using IFs?)

Yes — they’re essential. Especially when used as guard clauses. It’s the If-Else combination that is a root cause for maintainability headaches.

是的-它们是必不可少的。 特别是当用作保护子句时。 If-Else组合是造成可维护性头痛的根本原因。

还有很多额外的课程! (It’s a lot of additional classes!)

Indeed. As I’ve mentioned in another article, complexity does not originate from the number of classes you have, but from the responsibilities those classes take.

确实。 正如我在另一篇文章中提到的那样,复杂性不是源于您拥有的类的数量,而是源于这些类承担的责任。

Having many, specialized classes will make your codebase more readable, maintainable, and simply overall more enjoyable to work with.

拥有许多专门的类将使您的代码库更具可读性,可维护性,并且使整体使用起来更加令人愉悦。

Resources for the curious--------------------------Examples by Refactoring GuruExamples by SourceMakingHow to make your code more Object-Oriented by Zoran HorvatC# Design Patterns: State by Marc Gilbert
Image for post
Image for post

Nicklas Millard is a software development engineer in one of the fastest-growing banks, building mission-critical financial services infrastructure.

Nicklas Millard是发展最快的银行之一的软件开发工程师,负责构建关键任务金融服务基础架构。

Previously, he was a Big4 Senior Tech Consultant developing software for commercial clients and government institutions.

在此之前,他是Big4高级技术顾问,为商业客户和政府机构开发软件。

Connect on LinkedIn

LinkedIn上连接

翻译自: https://medium.com/swlh/stop-using-if-else-statements-f4d2323e6e4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值