I'm currently busy with a huge refactoring on a small e-commerce application where a customer can place Orders (for sandwiches etc). The customer has to place the Order before a certain time so that the company can guarantee that the Order will be ready on time. This is done by configuring certain Deadlines. There is also a deadline that tells us to which time a customer can modify or cancel an existing order. The actual deadline depends on the chosen delivery date and thus is different for each order.
At this moment we simply calculate the deadline on the fly whenever we need it. The deadline result is just a DateTime
. The calculation logic itself is already in one place (IDeadlineValidator
) as it requires a database call to get some extra data and we just don't want to repeat it all over the application (DRY principle). But this IDeadlineValidator
is being called throughout the entire application because the deadline is also used to manipulate the UI (show the Modify button and that stuff). But it has become kinda messy and I'm sure that there are better ways to do this.
My question is now: what are some of the best practices to determine whether an Order can be modified? I'm also looking for the best performance.
A couple of solutions I already came up with are:
CanModifyUntil
. The application then has to check if CanModifyUntil < CurrentDate
.CanModify
with default value true
and (re)calculate in the background for each half hour or so, until the value becomes false
.CanModify
to true
, calculate the deadline and then schedule a background job on the actual deadline that simply toggles CanModify
to false
.What are some of your thoughts?
If the deadline can be calculated upfront and it's the only factor that determines whether or not an order can be changed, I like the first option that you proposed of calculating it once and then storing the result. You can still do the check within a service method if you want to abstract it in case it ever changes.
This option could help you to optimise your front-end code a bit (I'm assuming this is client/server with a web client) - since you can do the check to enable/disable buttons on the front-end. Of course, to be safe in the event that someone calls your API directly, you'll still need to check it on the server side, but it means you're not making extra calls just to render the front-end.
The other two options sound overly complex - what if the timer fails to trigger for some reason? Logic is now decoupled and orders can theoretically end up in an invalid state because your state manipulation logic sits somewhere else.