0

I am thinking in a common orders and order lines example. The order has a state and depends on the state, I can do some actions or not.

I guess that a good option for that it is to use the state pattern. If I am not wrong, with this pattern, I should to have one action for each possible state to change the order from one state to another, so I would have AcceptOrder(), CancelOrder() and so on.

But I was thinking about this other option. To have only one action, UpdateOrder(), in which I can update all the properties, and one of the it would be the state. Then the update method would check if it is possible to update from the actual state to the new state.

In this way, I treat the state as another property more, and for the user I guess it is easier to understand, because if for one side it should to update "normal properties" and use the update method to update them (less the state) and for another side they should to use a action to update only the state, it would be a bit more confuse.

Also it simplifies the number of actions for the user, because if I have to have an action to pass to Accepted, another to pass to cancel and so on, it is more confuse and it would requier much more button in the UI.

Perhaps I am mixing the domain with the UI, but I am trying to have a general view, how to validate in the user and how to make easy to use, and another the domain that has its own design, but I guess that when you start with DDD, it is hard to focus and isolate completely the domain and don't think in another layers.

In summary, the idea would be to have a form in which the user can modify all the data and to have only one action, aupdate, to confirm the updates.

Thanks.

2 Answers 2

2

Depends on what you want to achieve I guess. But, just think about how amazon would look like, if instead of a proper workflow, it would just give you a form to "update" all the properties in its (internal) order model. It would be painful to use.

Same for code. Code should be used to communicate as much as possible with the reader / user of the code, i.e. other developers. Giving access to the raw data has zero information content about what workflows are supported, under what conditions and in what states.

If you are a DDD fan, your objects should always reflect the ubiquitous language. That means object names and method names should reflect the language of the domain. Is "update" domain language?

2
  • Perhaps for order there is few properties that a user should to change. But suponse for the address. An address can be change always the order is not send. So supopnse that the user has to set the street name, the zip code, the state, the country... The user set when create the order, but he realized that he wants to change the addres. Go to the order and have a form to set the address info. Isn't better to wait the user fill all the fields and the update? Because if not, which is the alternative? to have a button to change street name, another for country and so on? Commented Sep 22, 2022 at 15:02
  • I guess that would be something like changeDeliveryAddress or something like that. I could imagine that being part of the domain language. Commented Sep 22, 2022 at 18:11
1

About DDD
Be aware that "domain" does not mean the technical layer, like "UI", "business logic", "data access" or something like that. Domain means the business area and includes all technical levels. From UI, down to the database. DDD also recommend a technical seperation into layers. But thats happening inside a domain. So you may have a domain "order", which includes now all business logic and the UI elements around that business element.

About the logic
Let us think about an artifical example where your "order" can have 200 different states. Yep, quite artifical, but for me, using "extreme" examples help me to see some up- and downsides of solutions, which then could be also applied to real life situations.

Now with 200 states, having just one method "updateOrder" would need at least a switch with 200 cases (201 if you include a fallback default case). Thats.... ugly. We could then move the logic of each update case into its own method, which then validates if the update is allowed or not and does the state update itself. Still, a 200 case switch...
The other "extreme" situation would be an order with just two states. There the switch (or perhaps an if solution) is quite easy to read.

On the other side let us take a look at the state pattern.
200 states => we need 200 implementations (sounds ugly, but to stay truthy, we also would need 200 implementations of the logic in the above switch case). But each implementation is quite straight forward and only considers valid changes. That means, each state change implementation only needs to know those states that are could follow (to validate if the state change should be executed). The others could be ignored.
2 states => now the code is splitted in two implementations which makes it a bit harder to understand the whole state system, because we have to look into two implementations (just one for the switch case).

By the way "switch" does not mean that the "switch" logic is somewhere in the UI placed. I think it directly belongs to the state. Therefore i would create an order class which containes the current state AND the logic to change it.

And "state pattern" does not mean you have a "acceptOrder" and a "cancelOrder" method. There are just multiple classes (one for each state) which implements an abstract "updateOrderStatus" method. And the specific implementation then changes the state to "accept" or to "canceled". As a result the outside just have to call "updateOrderStatus" with the new wished state as a parameter, and the specific implementation of the current state does the magic.

That said, in my eyes it depends on multiple factors which design style to use. If the states will very likely NOT change and there are only very few states, then i opt for the switch version.
If the states are likely to change or there are quite some states (more then three or four i think), then i would opt for the state approach. Its easier to modify and for many cases easier to understand (at least what i think :-) ).

Now to the UI
If the business logic exports an "allowed state changes" function, the UI could ask the business logic which state changes are allowed and then show the appropriate interactions to the user (like multiple buttons, a dropdown, ...). So it does not need to know the logic and does not need to "show everything", but only those things that are possible.

For me the important aspects are that UI and business logic are cleanly seperated. Yes, the UI is dependend on the business logic, therefore if we change the business logic it may be that we also have to change the UI implementation(s). But changes in the UI can not interfere with the business logic as such.

1
  • Thanks. With state patter only it is changed the state, with the method UpdateOrderState(). But suponse if the order have more fields to fill buy the user, like comments and suponse much more, 20 for example. would I have a method UpdateComments() and other UpdateField2()... and so? Or it would be better to have a general UpdateMethod() to update all at once? Commented Sep 23, 2022 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.