تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Defining Primitive Obsession0:07

The next thing I wanna talk about is primitive obsession. That's right. primitive obsession is actually a code smell from Martin Fowler's book Refactoring, and it is our tendency as programmers to use the simple or primitive data types, things like strings, integers, and boolean values. We do this 'cause they're easy and readily available in all languages, but over time they actually limit us. In fact, they can cause us to write more code.

but over time they actually limit us. In fact, they can cause us to write more code to manage these primitive values, therefore, increasing the code's complexity if nothing else, simply because we're reading more code. Let's go back to that code snippet. Within Laravel we reviewed for dead code, it was around registering the authentication routes. Now we've just got a portion of this to kind of lock in and take a look, but our issue

Arrays as Problematic Primitives0:55

Now we've just got a portion of this to kind of lock in and take a look, but our issue before was that we were passing in an array and arrays are also a primitive type, especially in php because we use them for everything. They're kind of our catchall data type as we discussed in dead code. The problem with the array is that we could actually pass in an infinite number of options, even though we're only using confirm

that we could actually pass in an infinite number of options, even though we're only using confirm and verify, we could actually pass in whatever we wanted, even though it has no effect on the code. To guard against that, we would have to add some kind of validation to ensure that they were only passing in the correct set of options. That code would be rather complex. It would need to be some kind of array_diff on array keys and then ensure that those keys were only the ones

It would need to be some kind of array_diff on array keys and then ensure that those keys were only the ones that were available. Then we would need to throw a new Exception, maybe an InvalidArgumentException. The code calling this would then potentially need to catch that, all of which demonstrates the fact that we have to write more and more code to manage these primitive types. Now, there are other ways we could formalize this. Laravel has wonderful documentation,

Replacing Primitives with Options Object2:11

Now, there are other ways we could formalize this. Laravel has wonderful documentation, but you actually won't find all of these options in the documentation, and even if you did, code speaks louder than words and this code would still allow you to pass any option with no effect. So we'd much rather formalize this in the code. One alternative, instead of all the checking, would be to break these out into parameters.

One alternative, instead of all the checking, would be to break these out into parameters. For example, a bool to confirm and a bool to verify, and this puts us on the right track, but we're actually still just using more primitives and as we add more and more options, we've really just traded one code smell for another. That's primitive obsession for a long parameter list.

code smell for another. That's primitive obsession for a long parameter list. We need to break out of this primitive obsession and remember that we can use objects; passing some kind of object here would formalize the available options. That class might look something like this, simply containing a set of boolean properties on the surface. This might feel too simple. This class doesn't really do anything, but again, its benefit is in its use.

This class doesn't really do anything, but again, its benefit is in its use. For example, when we were registering our routes, we would now be able to say all routes and pass in a new offRoutesOptions object and we could pass in these options directly. We see that phpStorm completes these, but if we only needed to say, turn on the confirm route, we could use the name parameters in PHP to simply set the confirm option.

we could use the name parameters in php to simply set the confirm option. There's no denying this code formalizes the available options. Going back to our implementation by using it here, we would actually be able to simplify the checks here. Instead of the null coalesced array access, we would be able to check this property directly. Again, making the code less complex and more readable. Using objects also has the benefit of grouping

Coupling Data with Value Objects4:16

Again, making the code less complex and more readable. Using objects also has the benefit of grouping or coupling data together. Generally speaking, low coupling is a good thing in code, but when things change together, coupling them can be good. Let's consider a snippet of code from some banking software, a rather naive implementation to transfer some money between two accounts and we see that the amount and currency are passed in and they're debited from one account.

and currency are passed in and they're debited from one account and credited to the other. In looking at the code, we see that amount and currency are always used together. Having these passed in as primitive values may allow some flexibility, but in the real world you wouldn't change these individually. For example, one US dollar is not the same

these individually. For example, one US dollar is not the same as one euro, so you could never change the currency without changing the amount. Just like before, we could formalize that with an object, but also demonstrate the coupling between the two. This yields a money object where the amount and currency are passed and together to formalize and couple the two going even farther.

and currency are passed and together to formalize and couple the two going even farther. This money object is a classic example of a value object. Often value objects are immutable. What that means is when we create a money object, there's no way for us to change it. In this case, tin us SD, there's no way for us to change the currency or the amount at any point in time. To do so, we would need to make a brand new money.

Encapsulation with Range Object5:52

or the amount at any point in time. To do so, we would need to make a brand new Money object. Value objects help us avoid side effects in code, they're static so they can't change throughout the code base. Less change means less complexity, which means you have a code base that's easier to maintain. The final benefit I wanna discuss is encapsulation; objects give us a place to put additional logic, for example, methods or additional properties.

give us a place to put additional logic, for example, methods or additional properties. Let's refactor one last common code snippet to use objects. In this case, we see a min and a max. This can be represented as a Range object. Again, another classic value object. This Range object could not only formalize these two values, but demonstrates the coupling between them. Now with encapsulation, we can take this even farther. For example, we can add a method

Now with encapsulation, we can take this even farther. For example, we can add a method to encapsulate this relatively complex, compound conditional and instead streamline it to a single expressive method column. Comparing the before and after of this code snippet makes it easy to see the value of using objects and how it not only removes our primitive obsession, but makes the code more readable.

Avoiding Overuse of Objects7:11

and how it not only removes our primitive obsession, but makes the code more readable. Using objects should be part of our skillset, but we shouldn't overuse them. We shouldn't force them. It's important to remember that the goal isn't necessarily to use objects. The goal is to make the code more readable. Always review the before and after of the code when refactoring the objects.

Always review the before and after of the code when refactoring the objects to ensure it's more readable.

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