Dual Load/Save Objects in OOPHP - unnecessary dupl

2019-01-27 10:08发布

问题:

I have a (conceptually) fairly simple application spec that I'm implementing in PHP - the large part of it consists of loading project data, displaying it, allowing a user to edit it (potentially adding sections) and then sending said data back to the database.

I'm planning on approaching it thusly:

  • Have a set of basic 'Load' objects (E.g. ProjectLoad, FormLoad) that take an ID upon creation, query the database and fill themselves with the fetched data. These objects can then be used to fill the page elements.

  • Have another set of 'Save' objects (E.g. ProjectSave, FormSave) that take arrays (returned when the page is submitted), fill themselves with that data and then perform INSERT\UPDATE operations on the database.

Is this unnecessary duplication? I'm just getting a handle on OOPHP, and all of the advice I've seen so far seems to indicate that it is best to try and keep everything (objects, methods, etc) as focussed and single-purpose as possible. This seems to meet that criteria, but is there a better way?

回答1:

It looks like what you managed to brainstorm your way to two concepts:

  • the core idea behind Data Mappers

  • separation the logic for creating new entries and the logic for retrieving data (this idea is really important in CQRS, especially in context of Event Sourcing)

But I suspect that, while data mappers should be quite easy for you to grasp, the second, CQRS-related, part might be at least a year too soon for you to explore.

As for your questions..
Unless you do something stupid, there wouldn't be much duplication in your "load object" and "save objects" .. though, you probably will extract either one or two superclasses there.

The "advice you have seen" is actually called Single Responsibility Principle and is, TBH, is one is more nebulous concepts in OOP. It's like defining, what "porn" is - know it, when you see it.

And, if you want a recommendation for better approach, I would suggest to combine the read and write part in a singe data mapper. Kinda like this:

$project = new Entity\Project;
$mapper = new Mapper\Project($pdo);

$project->setId(43);
$mapper->load($project); //pulls data about project 43 from DB

if ($project->getDeadline() > time()) {
    $project->setStatus(Entity\Project::STATUS_OVERDUE);
    $mapper->save($project);  //pushes changed state to DB
}


回答2:

I can't tell if that is really duplication since it is still a concept and I think duplication really occurs during the implementation. As a concept you have done a good job to separate the concerns among your classes.

If you really are into OOPHP you might as well check topics about Design Patterns :

  • OOP Design Patterns - for basic (building blocks) design patterns.
  • Martin Fowler's Patterns of Application Architecture - advanced design patterns

According to Wikipedia:

In software engineering, a software design pattern is a general reusable solution to a commonly occurring problem ... Design patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.