mercredi 26 avril 2017

State Pattern for login and payment logic design

First of all thank you all in advance, this community makes the code around the globe so much better!

So, I´m designing a system to manage login routing and payments for customers to use a service.

I´ve decided that for my logic it would be better to use the State Pattern, so that each state knows how to handle the payment transactions gotten from another system, which already exists, to change state (there are some kinds of payment).

Also it would know which main page the customer should land in, as there are some different payment screens options for different kinds of customers.

Here is a snippet of my design, sorry for not putting any code but haven´t touched code yet.


Transaction (base class)
- MonthlyFeeTransaction
- CancelSignatureTransaction
- ...OtherKindsOfTransactions (subclasses)

(properties)
- Client client
- double Amount
- Date transactionDate
- ...otherProperties

(method)
-> registrate():void
(calls appropriate service methods to registrate itself in the DB)


ClientState (base class)
- NewClient
- UpToDateClient
- InadimplentClient
- CancelledClient
- ...OtherKindsOfClients(subclasses)

(methods)
getLoginScreen (): String
receiveTransaction (Transaction transaction)
...someOtherMethods()


The Transactions are what triggers change in the state, and some modifications in the DB will have to be made accordingly, which changes depending on the state flow. Ex: for a CancelledClient to become UpToDate the cancellationDate parameter must be set to null, which is not the case for a NewClient to become UpToDate, and so on.

I´ve thought of some ways to make this work. For example I could overload the receiveTransaction method so that there is one for every Transaction subclass, and put the state transition logic there. This way I would need to write new methods in ClientState subclasses for every new Transaction type, which doesn´t fell very OO.

Or I could have the Transaction object send a message to the receiving State object triggering the change, but then the Transaction object would have to know about ClientState methods, which is not desired from a business point of view.

So what I ask is: how could I loosen the coupling between these two classes, so that whenever I add a new Transaction subclass or a new State subclass I don´t have to make any modifications in the other?

Is there another design better suited for this?

If I can make the question anyhow clearer please tell me.

Thanks again!

Aucun commentaire:

Enregistrer un commentaire