1

I've been reading articles on Hexagonal, Onion, Clean Architectures, and other Domain-Driven Designs. A common theme they emphasize is decoupling components. From what I gather, this means the UI should be decoupled from the domain/business logic.

However, when I try to apply this concept to our project, I'm struggling to envision how we can remove all the domain logic currently embedded in the UI layer.

Here are the key domain logics we have in the UI:

  1. Model/View: We use JSON files where the model is tightly coupled to the data objects that the backend understands.
  2. Validators: Simple validations are included in the JSON files (which our in-house framework processes), but more complex validations are implemented in JavaScript. These often access the model at deep levels and apply domain-specific rules.
  3. Event Handling: This logic can also be quite complex. For example, if field A changes, we need to check fields B and C, compare their values with domain-specific strings, and then set a value on field D.

One potential solution we are considering is fetching the model/view JSON files from the backend via a REST API. But we’re still facing challenges with validators and event handling. We've experimented with using json-logic-js to send rules, but even with this, we still need to keep some logic (broken into generic pieces) in the UI code.

Does this approach seem clean? Or is there a better solution already out there?

3
  • It is way harder to break up tightly coupled unlayered code than it is to design code from scratch the right way, let alone trying to apply an architecture that you're still new to. I strongly suggest that your first hands-on experience is not refactoring an existing codebase.
    – Flater
    Commented Sep 30 at 8:56
  • Your overall approach may be well intentioned but it is deeply misguided. You're trying to shoehorn badly designed code into a format that inherently resists putting bad code into it, and you're doing it while stating that certain things have to remain the same regardless what the new architecture mandates. This is just not going to end well for you learning to do things the clean way.
    – Flater
    Commented Sep 30 at 8:59
  • Every theorist of architecture talks a good talk on decoupling. I've never heard of any of them who explicitly advocated for coupling under any circumstance. What hardly any of them talk about is what kinds of coupling are intrinsic or necessary to accept, or what the limits of decoupling are.
    – Steve
    Commented Sep 30 at 10:39

2 Answers 2

2

The way I approach separation of UI and domain/business logic is to mentally replace the UI with an oldfashioned paper form (and a scanner+ocr to get it into the computer system). Everything that must remain the same with a paper form input is business logic that must be handled outside the UI.

But that doesn't mean the UI cannot also parts of it, if that improves the user experience.

As an example, the business rules in the back-end must validate that all input provided by the user is valid. This is especially true if there is a separation between front-end and back-end, because a (malicious) user may have bypassed some or all the validations of the front-end.

But that does not mean the front-end cannot provide convenience validations to give faster feedback to the user about their entry or even to pre-fill answers based on preceding questions. All of that, I would classify as UI-logic and not as business logic.

Also, the decoupling intended by the various architectures mean that the business logic should be independent from how the UI works, but the UI can have knowledge of the business side.

0

There are some mental hoops to jump through.

  1. "Domain" logic has a flexible meaning For example, "when the user clicks buy, first show them an advert". People will say this is "business logic", but it's clear a UI layer thing. You could implement some Domain Logic later so say, "If the has_seen_ad flag is not true, mark the order CANCELED"

  2. Model = Data Object in web apps. Because you pass them between javascript and whatever you backend is programmed in, you can't add methods sensibly, and with modern Single Page Applications doing a lot of the work on the client it forces you into an ADM approach with Domain Services doing the logic

  3. Validation is a flexible thing that can happen in multiple layers. Generally we mean Front End Validation, ie the user sees a red tick and can't complete the form. Put this validation on the front end. as a separate component.

  4. Event Handling, just because logic is complex doesnt mean its "Domain Logic". Capture the event and fire off the domain logic which is in its own component

Overall it sounds like the main problem is this split between the front and backend. I would say, don't try to send code to run over the api. Either send a flag showing the type of code you might want to run. ie

{
   "form" : {
      "name" : {
         "type" : "text"
         "validationType" : "Name"

Or make a backend call

Post Form/Validate

{
   "name" : " bob"
   ...
}

{
   "name" : [ { "result" : false, "reason" : "starts with a space"}]
   ...
}

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.