در حال بارگذاری ...

Introducing Flag-Based Mute0:00

Let's talk about flags and why you might want to avoid them. So here I have a test class for muting a User, and we have two cases here. Let's very quickly go over it. Given I have two Users, John and Kate, if John mutes Kate, then Kate should be included as part of John's muted accounts pivot table, effectively. But you also see this third one. We're looking at an expiresAt column on the pivot table, and we want to ensure that it is set to null. And that's because, by default, when you mute a User, it is permanent. However, we also have a setting to mute a User for seven days, kind of a cool-off period.

And that's because, by default, when you mute a User, it is permanent. However, we also have a setting to mute a User for seven days, kind of a cool-off period. This person's getting a little too feisty. I'm not going to block them entirely, but I'm going to mute them from my feed for a week. Services like Facebook offer this. Okay, one more time. Given I have two Users, John and Kate, if John mutes Kate and then he passes that false flag, who knows what it is, but we can assume it's something related to a temporary mute. Anyways, if we do that, then that expiresAt attribute should be equal to a week from now.

flag, who knows what it is, but we can assume it's something related to a temporary mute. Anyways, if we do that, then that expiresAt attribute should be equal to a week from now. And that way we can check, all right, has it been at least a week? If so, we can remove that record. Otherwise, the person should remain muted. Okay, so I have a little production code for this, and those tests do pass. Let's take a look at the source code. All right, let's take a look at what I have here. Here's my mute method. So notice the signature.

Reviewing Mute Method1:32

Here's my mute method. So notice the signature. We mute a given User, and then we pass a flag here. Should it be a permanent muting or a temporary cooling-off period? And by default, it's set to true. So this is what we refer to as a flag. Notice the flag determines how the method proceeds. If we have a permanent muting, then attach that User to this pivot table here. Otherwise, we'll do the same thing, but I'm also going to include an expiresAt column, and that will be one week from now.

Otherwise, we'll do the same thing, but I'm also going to include an expiresAt column, and that will be one week from now. And that way we know when it can be safely removed. Now in terms of how we push the pivot table, it's a simple, Eloquent, belongsToMany relationship. Not fancy going on there. So yeah, if I run the test, everything is passing, but I don't love this. Now a flag very much can be useful, but especially in terms of what you expose to the outside world as part of your public interface or your public API, try to avoid it when you can. Because again, think six months from now when you come across this code somewhere in your

Replacing Flag with Method2:51

Oh, that's whether it's a permanent or a temporary muting. Okay, got it. But notice those extra steps that were required, all because this code was not clear enough. So let's see what we can do here. If I didn't want to use a flag, well now how do I clarify that this should only be a temporary muting? Well, I keep using that word, right? Let's work it into the method, muteTemporarily. Okay, now if I run the code, it fails. Let's make a pass.

Okay, now if I run the code, it fails. Let's make a pass. We're going to add a new method here called muteTemporarily. I still need to know who we are muting, but now I can remove this if else statement. So this is how we temporarily mute a User. And this is how we permanently perform that action. Let's get rid of all of that and we get something like this and we'll return in both cases. Now if we scroll back up, I no longer need to accept this flag. We've removed it entirely and I can update the docBlock. Now if I run the code again, it all passes.

We've removed it entirely and I can update the doc block. Now if I run the code again, it all passes. And the best part is now, because we removed that flag, I no longer have to mentally parse what the boolean is for. Six months or six years from now, if I look at this code, it's very clear. Oh, John is temporarily muting Kate. Now in our example, it was actually quite useful. We were able to remove that if else statement entirely. But there might be situations where once you extract a second method, the code is duplicated and you start realizing, well, other than a variable or an array, this is almost identical.

Avoiding Duplication with Options4:20

But there might be situations where once you extract a second method, the code is duplicated and you start realizing, well, other than a variable or an array, this is almost identical to what we had before and I don't want to duplicate myself. In those situations, simply defer to the original method like this. So now we're going to say, all right, a temporary muting is still a muting. So we'll call mute. However, as you'd expect, if we run the test, it's going to fail and that's because we're no longer setting the expiresAt column. Okay. It sounds like I want to pass that through.

Okay. It sounds like I want to pass that through. So expiresAt is now at a week. Now we can see, all right, well, it looks like the mute method should accept additional, we could call these attributes or options, anything you want. Now by default, it's going to be an array. And these attributes can be passed as the second argument to the attach method. Okay. So now take a look. If I run the test again, we're back to green, which means, again, in this particular example,

Guidelines for Using Flags5:23

So now take a look. If I run the test again, we're back to green, which means, again, in this particular example, I don't think it matters. It was still very simple. But surely you can imagine for more complex scenarios, this would be the way to go. One method simply defers to the other method. Now to wrap up, I'm not saying never use a flag, but before you reach for one, take a moment to ask yourself, if I instead create another method, would that remove the need for the flag entirely?

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟