4

Scenario:
An application is going to perform operations on an entity. That means retrieving it from storage, possibly making modifications, and then persisting those changes back to storage.

I'm hearing conflicting approaches.

  1. We should retrieve an entire entity from storage (like a repository), our application logic should modify it (setting its properties or calling its methods, whichever) and then save the entire entity.
  2. We should only query the properties we need to execute application logic. When we save changes, we should have storage methods for saving only the modified properties. This will allow concurrent processes to update different properties without blocking each other.

This assumes a predominantly anemic domain model. It's more likely that application (domain) logic will read and set properties on entities.

I realize that no two scenarios are the same. What factors would you consider when deciding which approach to take?


I can't describe the actual scenario. Imagine building a network of computer technicians who work both on-site and remotely, determining who is available to work where and when and what their skills are, and deciding where and when you will assign them to work to match the expected need to schedule appointments. There are approval workflows involved for scheduling.

The result of errors might be things like scheduling someone for appointments in one area when they aren't going to be there, scheduling too many technicians in one area where there's not enough need, scheduling an on-site session for someone who works remotely, or scheduling an appointment with a technician who doesn't have the right skills.

A technician might say they're available but need to change it. Or their skills might change, affecting the types of appointments they can do.

Scott Hannen
  • 1,064
  • 1
  • 7
  • 13

2 Answers2

4

The standard strategy I would recommend when approaching such problems is

  • start with the one approach which is most simple to implement in your current environment / context

  • when you run into issues (like performance or concurrency issues), adapt as needed

In a typical business application where you think of domain objects, repositories, and where you may have some ORM at hand, loading and storing full entities is often the most simple to implement approach. If that's your case, start with that.

For other situations, maybe when you are implementing a new use case on an existing system, where you cannot reuse any any of the existing code for some reason, and that use case makes only use of a certain subset of attributes, it can be simpler to query and update only the required attributes.

Doc Brown
  • 218,378
2
  1. We should only query the properties we need to execute application logic. When we save changes, we should have storage methods for saving only the modified properties. This will allow concurrent processes to update different properties without blocking each other.

This approach is flawed in many scenarios. For example say one process wants to update an order quantity and other the order item? You want ten apples but end up with ten oranges.

This forces you to add a "poor man's transaction" where you UI is always checking to see if anything has changed which you were editing and prompting the user to check for consistency.

Additionally, only getting the properties you "need" can exponentially increase the amount of code you need to write and edit when new requirements come along. If i was previously on getting the order item but now the requirement is to make it green when the status is InStock I need to go back though and change every layer. I probably even need to keep the old JustGetTheItemPartsOfTheOrder() method in case its used elsewhere. Doubling up on my code.

Its not always wrong obviously, objects can be too big to make uploading the whole thing everytime sensible, or you may have a small change on many objects "cancel all the order of apples! we ran out!", or you may want to save the change that was made rather than the entire object, "edited line 7 of the novel to read xxx"

My general guidance would be "write your application as if it hasn't got a datalayer" This forces you to think about you application in terms of code and objects rather than an interface for a database.

Ewan
  • 83,178