Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Agree on naming for data access objects Dao Vs Models in core platform and plugins #7540

Closed
mattab opened this issue Mar 26, 2015 · 15 comments
Closed
Labels
RFC Indicates the issue is a request for comments where the author is looking for feedback. Task Indicates an issue is neither a feature nor a bug and it's purely a "technical" change.
Milestone

Comments

@mattab
Copy link
Member

mattab commented Mar 26, 2015

The goal of this issue is to discuss within the Product team a common naming for DAO. By not having a common design here we are mixing several notations and it is causing confusion. To create the best open analytics platform, we need to get these things right :-)

These classes contain SQL queries and little/minimal logic around SQL queries.

So... shall we name them Dao, eg. https://github.com/piwik/piwik/blob/master/core/DataAccess/RawLogDao.php or shall we name them Model or some other name?

Once agreed we can change all current code to use the decided name. (this can be followed up in other issue or here)

@mattab mattab added the Task Indicates an issue is neither a feature nor a bug and it's purely a "technical" change. label Mar 26, 2015
@mattab mattab added this to the Piwik 2.13.0 milestone Mar 26, 2015
@mattab mattab changed the title Agree on naming for DAO Agree on naming for data access objects Dao Vs Models in core platform and plugins Mar 26, 2015
@mnapoli
Copy link
Contributor

mnapoli commented Mar 26, 2015

  • everything related to data access -> MyPlugin\Dao\SomethingDao
  • everything related to domain logic (no db queries here)
    • if it's a service: MyPlugin\Model\SomethingService
    • if it's a value object or model object: MyPlugin\Model\Something

Examples:

Piwik\Plugins\UsersManager\Dao\UserDao
Piwik\Plugins\UsersManager\Model\UserService
Piwik\Plugins\UsersManager\Model\User

@diosmosis
Copy link
Member

👍 for Dao\*Dao

Storing value objects in Model makes sense to me, but storing services seems strange. Doesn't Model invoke the idea of data structures and schemes? Maybe services could be put in Services\...?

@mnapoli
Copy link
Contributor

mnapoli commented Mar 26, 2015

Yeah we could, the idea is that Model contains domain logic (so services match that), I'd rather name it Domain but I'm afraid it might confuse some developers (model is a more widespread term than domain, mostly because of MVC). So anyway I don't really care, I'm fine with a Service namespace.

@diosmosis
Copy link
Member

To me Model brings to mind CRUD operations, or generally just delegating to services (which could exist on separate machines). However, if most developers understand models as encapsulators of domain logic, then it makes more sense to use Model. I'm not sure what most developers think, so I'll just retract my original comment :)

@kaz231
Copy link

kaz231 commented Mar 26, 2015

I agree with @diosmosis that Model in many PHP frameworks is correlated with DTO. Regarding to communication with data storage (database, cache, files etc.), I don't care if it will be a DAO or Repository (IMO definition of both is similar). More curious to me is how you want to handle such things:

  • creating of query (plain text, query builder or query object)
  • managing of source connection (opening and closing)
  • data mappers

The problem is simple if we are limited to SQL databases, but if we would like to extend our technology stack with e.g. nosql, graph dbs etc, then it's much tricky to create a good architecture.

@mnapoli
Copy link
Contributor

mnapoli commented Mar 26, 2015

Let's have Model\Something and Service\SomethingService then.

A repository is different from a DAO as it represents a collection of objects (model objects). In Piwik I have yet to see objects being used (or at least used for real). For example there are no objects to represent users, array of values are used instead: https://github.com/piwik/piwik/blob/master/plugins/UsersManager/Model.php#L43-58

If some plugins indeed introduce the concept of repositories and associated model objects we could use the repository naming for this specific case, but currently (at least in Piwik's codebase) what we have are DAOs.

See also this question that sums up the difference pretty well.

More curious to me is how you want to handle such things: […]

I don't expect any refactoring in the codebase to happen now. The goal of this issue is mainly to define the naming to use for new classes and existing classes that will be refactored. But this is just a renaming, it doesn't imply introducing ORM (data mapper), changing the way the database is handled or how queries are created. Those are separated topics.

The problem is simple if we are limited to SQL databases, but if we would like to extend our technology stack with e.g. nosql, graph dbs etc, then it's much tricky to create a good architecture.

Different topic (but I agree it's an important one). Naming our classes DAO doesn't affect the locking to MySQL.

@mattab
Copy link
Member Author

mattab commented Mar 26, 2015

👍 to use Model as classes name for encapsulating the SQL queries accessing one or several db tables.

we started using it quite a bit already as there are 15+ Model classes in core and pro plugins.

@mattab
Copy link
Member Author

mattab commented Mar 26, 2015

Regarding Services I don't see examples in codebase - how would we use it exactly, is it like the logic encapsulated between the Controller/API and Model classes?

@mnapoli
Copy link
Contributor

mnapoli commented Mar 26, 2015

👍 to use Model as classes name for encapsulating the SQL queries accessing one or several db tables.

Nope those classes should be renamed (not necessarily now)

Queries go in DAO, those classes are meant to handle persistence. Model classes are objects that represent an instance of something (e.g. a user, a request to track, an alert, a report, an email, a date…). Model classes can contain domain logic related to themselves (e.g. a date can modify itself, etc.). Those are the classes that contain state. Piwik currently uses a lot PHP arrays instead of model classes.

Services are singletons (through the container, not actual singleton getInstance() stuff) that contain domain logic. They do not contain any state (stateless) like DAO. So basically it's everything that exist in controllers, commands, or other classes except DB queries. A little bit like API classes, except API classes are actually controllers so it's often confusing to put logic in there because it can be accidentally exposed. Putting it in services makes it easy to call from other parts of the code: it's meant to be reused.

To sum up:

  • DAO: persistence (i.e. DB queries)
  • Model: state (describes something)
  • Services: everything else

@mattab
Copy link
Member Author

mattab commented Mar 26, 2015

Ok, so next steps would be:

  • we are consistent in using Dao across core platform for all SQL access from all future written code
  • estimate how much effort it would be to refactor most of SQL currently spread in codebase to be all within Dao classes.
    • I reckon here there is a lot of value to spend bit of time to refactor and be consistent across core + official plugins (as bonus, it will be a nice small step in the right direction to later allow the community to add Postgresql support to Piwik Provide Postgresql support for Piwik #500)

@mnapoli
Copy link
Contributor

mnapoli commented Mar 26, 2015

For being able to use alternative storages, I think there are 2 options:

  • database abstraction: we need to replace the DB classes for something that abstracts the details of SQL queries so that they can run on any DB engine (we can write our custom implementation or e.g. Doctrine DBAL), the DAO should use the new methods but there are still 1 DAO for each database (unless advanced queries specific to postre/mysql in which case we can have multiple DAO implementations: can be useful to optimize specifically some parts)
  • persistence abstraction, e.g. store stuff in RDBMS or NoSQL or whatever: that's where having several implementations of the same DAO is useful (e.g. one DAO that stores in DB, one that stores in Redis, and you can switch between them)

@diosmosis
Copy link
Member

Has anyone thought about the placement of services? Ie, should they only be defined by plugins or can they exist in core? If they can exist in core, how would they be organized? Since all the important Piwik logic should ideally exist in services, I think it makes sense to organize Piwik around these services (which may not actually exist yet).

If we can put services in core, I think it would be good if the second level namespace in Piwik\ was for core services, eg, Piwik\ArchiveInvalidation\ArchiveInvalidator, then all classes related to the services, could be stored within those service namespaces w/o adding to clutter in core.

Or we could put these services only in plugins. Eg, the ArchiveInvalidator service and possible future services like an ArchiveAccess service (what I imagine the future of the Archive.php class would be) could be put in a plugin dealing w/ report caching (ie, the archive tables).

@mattab
Copy link
Member Author

mattab commented Mar 29, 2015

Created follow up issue #7571 refactor most of SQL currently spread in codebase to be all within Dao classes

@mattab mattab added the RFC Indicates the issue is a request for comments where the author is looking for feedback. label Mar 29, 2015
@mattab
Copy link
Member Author

mattab commented Mar 29, 2015

Regarding discussion about Services I created separate issue here: Discuss how we define, name, and namespace Services objects #7572 - feel free to comment there with your thoughts!

@mattab
Copy link
Member Author

mattab commented Mar 29, 2015

@piwik/core-team it seems we all agreed to use Dao class name suffix for objects that encapsulate SQL queries. Let's do this from now on! and see #7571 for the next step.

@mattab mattab closed this as completed Mar 29, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFC Indicates the issue is a request for comments where the author is looking for feedback. Task Indicates an issue is neither a feature nor a bug and it's purely a "technical" change.
Projects
None yet
Development

No branches or pull requests

4 participants