Tuesday, February 21, 2006

Patterns: Gateway Pattern

One of my favorite patterns is the gateway pattern. Basically it is setting up one class that all requests for a certain action run through. The time I use this the most often is when accessing an external service.

For example lets say that I use an external service multiple times in an application (in this case I am accessing over a webservice but it could be com, remoting, a database, almost anything)

In my example I have an external web service that I use to find the customers ID via a phone number.

3 Public Class Payment

4 Public Function CreatePayment(ByVal customerPhoneNumber As String, ByVal amount As Decimal)

5 Dim wsPerson As New com.example.Person

6 Dim personId As Integer = wsPerson.GetId(customerPhoneNumber)

7 Dim paymentId As Integer = Data.CreatePayment(personId, amount)

8 Return paymentId

9 End Function

10 End Class



12 Public Class Refund

13 Public Function CreateRefund(ByVal customerPhoneNumber As String, ByVal amount As Decimal, ByVal paymentId As Integer) As Integer

14 Dim wsPerson As New com.example.Person

15 Dim personId As Integer = wsPerson.GetId(customerPhoneNumber)

16 Dim refundId As Integer = Data.CreateRefund(personId, paymentId, amount)

17 Return refundId

18 End Function

19 End Class


Now if we ever need to change the service we are using or how it is implemented (i.e. the web service gets changed to remoting or the method to get a person changes) we need to change it all over our application. So to fix this we create a gateway class that pipes all calls to the remote service through it:

2 Public Class PersonGateway

3 Public Shared Function GetPersonId(ByVal customerPhoneNumber As String) As Integer

4 Dim wsPerson As New com.example.Person

5 Return wsPerson.GetId(customerPhoneNumber)

6 End Function

7 End Class



We then change our payment and refund classes to use the new gateway:

10 Public Class Payment

11 Public Function CreatePayment(ByVal customerPhoneNumber As String, ByVal amount As Decimal)

12 Dim personId As Integer = PersonGateway.GetPersonId(customerPhoneNumber)

13 Dim paymentId As Integer = Data.CreatePayment(personId, amount)

14 Return paymentId

15 End Function

16 End Class

17

18 Public Class Refund

19 Public Function CreateRefund(ByVal customerPhoneNumber As String, ByVal amount As Decimal, ByVal paymentId As Integer) As Integer

20 Dim personId As Integer = PersonGateway.GetPersonId(customerPhoneNumber)

21 Dim refundId As Integer = Data.CreateRefund(personId, paymentId, amount)

22 Return refundId

23 End Function

24 End Class


Now we have all calls to the external service in one place. Now we can make changes easily. For example say that the develpers of the Person web service change the method signature to require you to supply a username and password to call the method to prevent outside applications for getting customers information we only have one place to change it:

2 Public Class PersonGateway

3 Public Shared Function GetPersonId(ByVal customerPhoneNumber As String) As Integer

4 Dim wsPerson As New com.example.Person

5 Return wsPerson.GetId(customerPhoneNumber, "Kudos", "QWERTY")

6 End Function

7 End Class


This also could allow us a central point to validate the customerPhoneNumber if we wanted as well. By using this methodology it is also easier to create a dummy webservice for testing purposes that allows the application to be debugged without having to rely on an external webservice.

0 Comments:

Post a Comment

<< Home