Use Service / Provider in Model class

Hello, I want to do this question for people who have more experience than me to know if my planning is right or not.

We are going to suppouse we are develping and Ionic3-Angular app where we have a CRUD for “Clientes”. I have read that right way is:

  • Cliente Model: Class where I define attributes.
  • Cliente Service / Provider: It will manage database communication getting, modifing and saving data.
  • Page: Where I call load datad and show.

All examples I found should be:

  • They instance model Cliente in Page.
  • They inject Service / Provider Cliente in Page.

To load data:

  • From Page they load data throw Provider and it assign data to an object (type CLiente).

Now I’m going tolaunch my doubt. Could be better implement data access and manage directly in Model?. I have done small projects with this but I can found any example where people do this and may I’m in a mistake. I mean:

For exmple I’ll have a Client Class with these methods:

static load(cs:ClienteService,id):Cliente{
//function that receive provider and use it to access data with the other parameter (id of the Cliente)
}

guardar(cs:ClienteService):boolean{
// function to save object throw the ClienteService parameter
}

ClienteServicio will be injected in Page and will be passed to Model as parameter function if necesary.
By this way logic, check data, etc… will be manage at Model.

I hope I explained it and get advice from community.
Thanks so much

This may be a religious argument, and you should wait to see if somebody comes in with a different opinion, because mine shouldn’t be the only voice you hear or listen to.

That being said, I strongly dislike this sort of design, which I call “smart data”, for a whole host of philosophical reasons, and two major technical ones, one of which you have already identified: the fact that you have to pass a ClienteService to everything a model class does means that you can’t really decouple model objects from service objects, and makes for very clunky code. The other technical problem is that it is hard to marshal and unmarshal “smart data” objects to JSON, which is a very common thing to want to do with them.

So my recommendation is to make all of your business-level things be interfaces instead of classes, putting all of the intelligence in the service instead of the data container. JSON unmarshalling is now free, and you don’t have to feed service references into objects that don’t really want them in the first place.

Check how to implement an Active record pattern.

You can get inspiration with TypeORM which is an ORM that can be used with both Active Record and Data Mapper pattern (https://github.com/typeorm/typeorm/blob/master/docs/active-record-data-mapper.md). It uses the same structure as your “static load()” and “guardar()” method except that there’s no need to pass the service as a parameter, a reference to the service is already set to a static field in the model class when a database connection is initialized.