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

Introducing Sprout and Wrap0:00

How can you implement new functionality the right way without having to invest the time in refactoring? That's the most critical question most of the developers ask. Lucky for us, there are two techniques we can use to do just that. The sprout and wrap techniques. Let's look at the same requirement we had earlier of adding wise as a new payment processor. But this time, we'll explore how we would use the sprout technique to add it without having to refactor the rest of the code. Now, when it comes to wise as a separate payment option,

Sprout Wise Processor0:27

without having to refactor the rest of the code. Now, when it comes to wise as a separate payment option, we can still use the best practices that we have outlined. So, we would still be able to create a new Wise class and handle everything there while not touching a lot of the existing code. Let's see what that would look like. I have this WiseProcessor class from earlier, and we can keep it as is. Just rename it here because we forgot to do that before. So, this class has a processPayment function. And following SOLID, we want to depend on abstractions,

So, this class has a processPayment function. And following SOLID, we want to depend on abstractions, not on concrete implementation. So, having this interface set right now when we create this first class will enable us to create code that is better at scalability and maintainability in the long run. Okay, so how can we approach this so that we can use this new structure for wise but still rely on the current payment structure or the current class that we have for managing everything? Again, I'll create my constructor here.

or the current class that we have for managing everything? Again, I'll create my constructor here and also go back to adding that paymentProcessor property. And now in the constructor, I want to set it to wise only. So, all of the other methods, all of the other payment options will be handled in this class in the same way that they are right now. I'm not touching them, I'm not refactoring anything. I'm just adding this property which will define the processor for wise so that for wise and any other payment option that I would like to create from now on, I'm going to rely on the solid practice and just call it from the old code.

so that for Wise and any other payment option that I would like to create from now on, I'm going to rely on the solid practice and just call it from the old code. I need to include Wise class here, services, WiseProcessor. So, this is the place where I'll need to adjust. And the sprout technique is basically suggesting that you create the new functionality as a new code elsewhere which can be tested and which can follow all of the best practices that you have outlined for code design and architecture. And then within the old code, you just reference it or call the new method from the old code. So, here we'll say paymentType or call Wise. And this method over here, it can be tested in isolation.

So, here we'll say paymentType or callWise. And this method over here, it can be tested in isolation. It doesn't have any dependencies on concrete classes. It could easily be mocked in the test. So, it follows all of the best practices that we have outlined within our project structure. And what's even better, it doesn't affect this old code too much so that the code doesn't get more vulnerable over time. It gets better structured and more tested. So, over time, if we start implementing all of the new functionality this way, then we'll get code that's much more resilient and much better organized.

Wrap Technique Scenario3:24

So, over time, if we start implementing all of the new functionality this way, then we'll get code that's much more resilient and much better organized. Now, for the wrap technique, let's explore a different scenario. For example, for compliance reasons, we want to start generating invoices automatically for every process payment. Now, the task you have at hand is to automatically generate a new invoice before a payment is processed and then mark a speed if the operation was successful. To do this effectively, we can utilize the wrap technique, which is basically stating that you can wrap your legacy code in your new code so that the code that you add can still follow all of the best practices.

Wrapping Legacy Method3:57

which is basically stating that you can wrap your legacy code in your new code so that the code that you add can still follow all of the best practices and you wouldn't have to refactor existing code. Let's look at it in a more practical way with our example. So, we have the processPayment method over here, and that is the legacy one. Following the wrap technique, we want to move this code to a new method, which we'll call processPaymentLegacy, for example. And I'll just rename this for that purpose and create a new one, public function processPayment, which will have the old name. And from here, I will just call the legacy method.

public function processPayment, which will have the old name. And from here, I will just call the legacy method. So, right now, we haven't changed anything. The processPayment method exists as it did before, and it's just calling a new method where we have transferred all of the legacy code. What happens with the wrap technique? What we want to do is add the full functionality again, following the best practices, as a new code. So, we can still apply that open-closed principle within our Payment class and say, for every new code, for every new functionality that we want to implement,

Adding Invoice Service Hooks5:05

So, we can still apply that open-closed principle within our Payment class and say, for every new code, for every new functionality that we want to implement, we will create new code outside, test it, design it well, so it's maintainable, breathable, and easy to extend, and then we will just reference it in our Payment class over here. And let's say we have created an InvoiceService for this purpose. We would do something like this, invoice, call the InvoiceService, and create an Invoice for this payment. Then our legacy code would execute, and after that, we want to use that InvoiceService again to mark the Invoice as paid.

Then our legacy code would execute, and after that, we want to use that invoiceService again to mark the invoice as paid. So, invoiceService, markPaid. Let's just get the result and say if the result was transactionSuccessful, then run this invoice. The wrap technique is basically helping you to extend the existing code by calling new methods before and after the actual legacy code. The sprawl and wrap techniques allow you to add new code that's well-designed and test it without introducing significant changes to the old code base. The good thing about this is that it doesn't require the investment of additional time.

Benefits and Summary6:34

and test it without introducing significant changes to the old code base. The good thing about this is that it doesn't require the investment of additional time for refactoring, while at the same time, doesn't contribute to creating a more complicated mess in your code. So, most of the time, this would be your go-to.

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