سؤال

I'm trying to split the use of a business entity (e.g. a post) thought an application uses, trying to obtain a clean architecture

So I will likely have:

  • A class model, where the business logic lives
class Post {

    private text: string;

    public constructor(text: string){
        this.text = text;
    }

    public getText(){
        return this.text;
    }

    public setText(text: string){
        this.text = text;
    }

    public clearText(){
        this.text = '';
    }

}
  • An interface for data transfers
interface PostDTO {
    text: string
}
  • And an interface for the data access (imagine this like a class highly dependent on an ORM framework)
interface PostDAO {
    schema: {
        text: string
    }
}

I got several pros in doing this:

  • Isolation in business logic, I'm able to write pure unit tests without the use of DB, etc.
  • Complete control of who receives what (e.g. a client can receive formatted data from the application or a database can save entity fields according to its available types)
  • Use of repository pattern, the clients (like controllers) that use the repository will receive always pure classes with business logic that clients can use

However, what bothers me is the amount of work required to make a small change in a model, while saying adding a field

Assume that I want the application to manage authors along with posts, I would have to:

  • Edit model adding the author field, with changes to the unit tests
  • Changing how an author is saved and loaded between the model and the DTO (I usually keep an intermediary mapper class, in this way the application is not dependent on which data source is used and how, if this change I just have to write another mapper class that know about the new data source driver/ORM)
  • Change the ORM schema, modify and test integration tests
  • Change DTO interface, modify and test integration tests

I'm doing this for a while and I'm perfectly fine with it but:

  • Am I doing this terribly wrong and I don't know it?
  • Can I simplify this process? (Note that this question want to be agnostic about magic frameworks and DBs)
  • Am I (gulp) missing something in this process?
هل كانت مفيدة؟

المحلول

Keeping things clean requires effort.

Separating concerns has a lot of positive effects, like you mentioned. Mixing concerns on the other hand (like database with domain) introduces technical complexity. As software developers we should be focusing on business complexity. For me that means additional effort should result in reduced technical complexity. Every layer comes at a cost, so you should have as little layers as possible, but as many layers as required.

So no, what you're doing is not wrong, if you can reasonably justify the effort. For a simple CRUD system (like your example) this might be overkill, but when there are some business rules involved it seems perfectly fine.

نصائح أخرى

However, what bothers me is the amount of work required to make a small change in a model,

In other words, it gets unmaintainable. Don't get me wrong, I'm not saying you are doing it wrong, in fact I think you are doing it correctly, and in the process you uncovered a real problem, and that is, that this architecture just a bad idea to begin with.

It gets actually much worse than what you are experiencing now, when there are overlapping use-cases, flags that change some attribute's meaning or interrelated data attributes are changed, updated or introduced. It works only on small projects where everything fits in your/teams head.

There are alternative (i.e. better, more maintainable) designs. Read up on object-orientation more, and try not to make everything "pure" just for the sake of it, be a lot more pragmatical. Seems to me that little voice in your head is saying the right things :)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top