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

Applying SOLID with Interfaces0:00

When it comes to structuring our code for easy maintenance and extension, solid design principles are an excellent guide throughout the process. The first thing to ask ourselves is how to organize our code in a way that will make it easy for us to navigate through it. We'll start by creating interfaces for what our program needs, following the Interface Aggregation Principle, or DI, in SOLID. According to this principle, your code shouldn't depend on things it doesn't use. So as a guide here on how to create interfaces that will provide the code structure which is easy to understand, think about small and specific interfaces that clearly describe the purpose they serve.

Defining PaymentOption Interface0:39

is easy to understand, think about small and specific interfaces that clearly describe the purpose they serve. This will make it easy for us to understand what a particular part of the code does, and as a result, it will make it much easier to maintain it. We'll start by creating a PaymentOptionInterface, and that one will define all of the methods for managing the payment options. Go to your Contrast folder over here, New File, New PaymentOption.php, and define the interface. Copilot is really handy over here, it makes things much faster, I'll just rename this method to getFields because I don't need that one. getFields will basically return the field configuration for every payment option that

method to GetFields because I don't need that one. GetFields will basically return the field configuration for every payment option that we have. The purpose of it is to enable us to easily display everything on the frontend and abstract the whole functionality well. Next, we also want to be able to get the values that a user has set. This one will receive the ID of the user. Okay, moving on next, public functions for storing the details for making a payment option. And note that over here, all the specific methods have received a user ID, and this is assuming a one-to-one relationship in the database, so any user can have a payment method.

And note that over here, all the specific methods have received a userId, and this is assuming a one-to-one relationship in the database, so any User can have a payment method of a specific kind only once. Set the details and make it primary or not. We'll need the lead, again receiving the userId, and finally make primary. This will set the selected option as primary, our leadUserId over here. Okay, so this sets our payment option interface, it's small, it's specific and it completely outlines how every payment option should behave in terms of management. Next, we need to create all the specific payment options that we're going to implement. So I created a separate directory here, services, and then paymentOptions inside it.

Creating Payment Option Classes2:48

Next, we need to create all the specific payment options that we're going to implement. So I created a separate directory here, services, and then paymentOptions inside it. This will house all of the specific payment options that we're going to implement. And I'll start with Wire, it's the first payment option that we want to implement here. I need to use the contract that we've created, so EndOption, and now we have CrossWire Incurrence EndOption. Again, using a compiler for speed of development, I'll work just on the specific implementation here, we can leave it blank for now. This is the structure that we need, have all of the methods implemented in the Wire class.

Implementing Store Logic3:38

This is the structure that we need, have all of the methods implemented in the Wire class. Now I want to do the same for Payometer, so let me just duplicate this, and now I have two concrete classes that implement my payment option interface. Now I'll start with a quick try-catch block over here, and what I want to do is first get the fields that I have defined for all of the wire payments, then I want to create an empty array, $wireDetails, and next I will look through the fields and fill this empty array with all the wanted values. This suggestion seems like a good one, I just want to add this check here, okay, else, let's throw in an Exception.

Explaining Field Configuration Structure4:27

This suggestion seems like a good one, I just want to add this check here, okay, else, let's throw in an Exception. Now before we continue, I want to quickly demonstrate the structure of the field so everything can be more clear. I have created it as an array here, in real life, in a production system, this would go to the database, but for simplicity, let's look at it as is right now and see how it would look like. Basically, it's an array of objects, every object has a name, type, label, required, and style as attributes, and all of these are important for displaying the fields on the frontend.

and style as attributes, and all of these are important for displaying the fields on the frontend. So this gives us a good structure to display everything without having to change the views whenever we implement a new method. And what I have done in the score method below is, I'm checking for this key, and it returns the name of the field. The database structure that I have is using the same names for the column value, so if the field is named bank_account_name, then the column in the database would be bank_account_name. And this is how that works.

name. And this is how that works. I'm checking if the data for bankAccountName, for example, is set. If it is, just filling out the details of the array that I want to store. And finally, what we want to do here is, I have paymentWire, my model. I want to do, yes, updateOrCreate, sending it the userId, if the wireDetails for this userId exist, then this would update the existing record, otherwise it will create a new one with the details that I'm providing. And I want to return this. The catch, let's just keep the exception.

And I want to return this. The catch, let's just keep the exception. This is diminishing the value of the try catch block, but just for simplicity, let's keep it like this. In real life, you would likely do something else here. Now quickly before we proceed, let's do the same in the Pioneer service class, and I will just copy this, it makes things quicker. So store, I have something like this. I just want to change this instead of paymentWire, which I have in Pioneer. Okay, that should do it.

Controller Selection and Testing6:50

I just want to change this instead of payment wire, which I have in Pioneer. Okay, that should do it. Let's go to our controller and test it out to see whether everything works as expected. Now in my controller, I have a store method. I have created this PaymentStoreRequest, which is a form request that's supposed to validate the user input. We're not digging into that right now. What I want to do here is check the user input to see whether the user has selected wire or Pioneer as the payment option. And based on that, I want to handle the response in a different way.

or Pioneer as the payment option. And based on that, I want to handle the response in a different way. Now the first thing I want to do is check the payment type on my request. If it's wire, I want to create a new instance of the Wire class. Otherwise, I will create a new instance of the Pioneer class. And now that I have the instance of the class, I will just call the store method on the object that I have instantiated. So here I have paymentStore, using the ID of the user, and then passing in the whole request because it has already been validated and I know that it has all of the required info to proceed forward.

request because it has already been validated and I know that it has all of the required info to proceed forward. Let's see how all of this works now and whether we need to do some adjustments. Right here we have two different payment options, Pioneer and wire transfer. All of the fields are generated dynamically depending on the request structure, so we're good there. And now to make it quick, I will just enter my email to set Pioneer as the preferred payment option. Let's say TestedExample, submit it, we have an error, and we have a fields method instead of getFields here, so let's quickly update that.

Let's say TestedExample, submit it, we have an error, and we have a fields method instead of getFields here, so let's quickly update that. And also in wire because we just copied this. Okay, TestedExample successfully saved.

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