I am starting developing in a new architectural paradigm over some legacy code we have. Let's call the different paradigms v1 and v2.
On v1 we had models for different domains (e.g games) that nested all the information of the entity and also of the attributes - many times mixing what a entity was and what an attribute was. So you could get a response that nested everything related to the domain when you hit a endpoint. E.g/ v1/games would bring you the game + the players + the teams + the arena.
On v2 we're trying to be more resource oriented so you actually get the resource you're querying for (e.g) - You have a endpoint for v2/games, and then you'll have an endpoint v2/games/{id}/players. With the former you'll get games objects and in the second you get players objects. I think it's self documentary by the path - You know what you're going to get by looking at the request you're making.
On v1 we had this huge models where everything was included - whatever we saw as an "attribute" of the domain. So our actual model would include the object to the related "attributes" - E.g/ Games objects would contain a players objects array.
Whenever you were getting or posting you would actually user the same model, you would just get more information (nested objects) on the GET and some fields weren't required for the POST (e.g/ you wouldn't need to send the players with your post - we had a separate endpoint for that).
class Game {
public $id;
public $datePlayed;
public $players = [];
public $homeTeam = [];
public $awayTeam = [];
}
On v2 models, we do an actual representation of the database table (like the active record approach of modeling were the model is based on the persistence layer). So the game model would not include players (since that is a different object altogether).
class Game {
public $id;
public $datePlayed;
public $homeTeamId;
public $awayTeamId;
}
So far I think the end result is very good because we're actually getting the resource we need and not a nested version with a lot of verbosity and unnecessary data.
However I have a new challenge now. There are endpoints that need to return responses with more information which will not be the actual database representation. Since we're not on a perfect world and I don't want developers that use our API to actually make tons of request for all the attributes I need to come up with a solution that helps me deliver them some basic information of the related resources.
So for example returning to our Game endpoint -> for creating I do want them to send me a payload that is the exact database object
{
"datePlayed": "2016-04-29T17:20:08+00:00",
"homeTeamId": 5,
"awayTeamId": 15
}
But for the GET I would like to decorate the response with basic data (not the whole object but just enough so that the developer get the basic information so that they only make a new request to get the complete related resource but not the basic information).
{
"datePlayed": "2016-04-29T17:20:08+00:00",
"homeTeam": {
"id": 5,
"name": "Killer clan"
},
"awayTeam": {
"id": 15,
"name": "Retry team"
}
}
At first I delegated this responsibility to the controller->repository who would create a new object upon request and return it on the GET method but would validate the POST and PUT requests to the actual model. However this doesn't seem too maintainable on the long run since you have to dig into the code to understand what you're sending.
So I gave it a long thought and I have an idea to create a new set of models with the convention Stub (the part of a check, receipt, ticket, or other document torn off and kept as a record) that will declare the structure of the response. Eg:/ I would create a GameStub model class like this
class GameStub {
public $id;
public $datePlayed;
public $homeTeam = [];
public $awayTeam = [];
}
I think placeholder or metadata also are good name conventions, but the gist is the same.
What do you guys think of this solution? Does it make sense?
Makes definitively sense because it´s a good approach to decouple your application from the api.
Resources in API != application models.
I use the following structure in my applications:
Model
- Game (This is your model)
Param
- GameParam (Model / Param / Resource which you want to provide over the api)
Converter
- GameConverter (Converts the Model into a Param and Param into a Model)
Part of it makes a great deal of sense but I did not understand your stub metaphor and how it relates to the problem.
So GET /games/gameId would normally just return team ids. To get more team information (such as team name) the user would then use GET /teams/teamId. You want to avoid the additional queries by sending some (but not all) team information as part of the game query.
So how would you know what additional information a particular request needs? What if (for example) some request needs the coach's name? Seems like you would be trying to guess what was needed and eventually end up sending everything again.
Have you looked at Facebook's graph query language? http://graphql.org/
The basic idea if to allow the request to specify what information they really need. So you might have GET/games/gameId?want=teamName,coachName
Then it is up to the server to figure how to return the necessary data. I'm not suggesting using graphql in your application. It's almost certainly overkill.
But maybe giving the consumer some ability to specify what they need might help.
And by all means, take advantage of a pattern called Command Query Responsibility Segregation (http://martinfowler.com/bliki/CQRS.html). Anything to do with creating or updating objects should be in it's own space. Treat querying independently.
Related
I'm a novice, but struggling hard to implement this interactive application I'm working on "the right way" or at least a good way in terms of scalability, maintainability, modularity, development speed and tool independence. That's why I chose the REST design guides and a framework which implements MVC.
However I can't get my head around where to put what in the following situation and any input or reading material from a more experienced developer in this techniques would be greatly appreciated :
I'm developing a single page web app which creates a resource that has several nested resources within. In the create methods and alike, I need to call the create methods from the nested resources. Right now every GET request is responded with a JSON, which the front end then parses, shows and add dynamically to the page accordingly. The question is : where should this create and store methods from nested resources be, in the controller or in the model?
Currently, my approach is : since the controller function is to handle user input, interact with model and return the view accordingly, the nested store methods are in the model since they're not created independently, their create methods are in the controller since they're requested from ajax calls, but this isn't nested, and so on. I'm worried that this is too mixed up and not general.
Am I ok ? Am I mixed up? I don't wanna make a mess for my coworkers to understand. Theory becomes tricky when applied..
I'm gonna have a go at this. I am myself still learning about this as well, so if any information is wrong, please correct me.
In terms of scalability, you should always be able to create any model independently, even though at this point it appears not strictly necessary. The REST paradigm stands for exactly this: Each model (a.k.a. resource) has its own (sub)set of CRUD endpoints, which a client application can use to perform any action, on any composition of data (compositions in which elementary entities are mostly the models you specify).
Furthermore, a model should be concerned with its own data only, and that data is typically found in a single table (in the case of relational datastores). In many cases models specify facilities to read related resources, so that this data can be included when requested. That might look like the line below, and the response is ideally fully compliant with the JSON API specification:
GET //api/my-resources/1?include=related-resource
However, a model should never create (POST), update (PUT) or delete (DELETE) these relations, not at all without explicit instructions to do so.
If you have a procedure where a model and its nested models (I assume related models) are to be created in a single go, an extra endpoint can be created for this action. You'd have to come up with a sensible name for that set of resources, and use that throughout your application's HTTP/support layer.For instance, for creation of such a set, the request might be:
POST //api/sensible-name { your: 'data' }
Keep the { your: 'data' }
part as close to a typical JSON API format as possible, preferably fully compliant. Then, in your back-end (I suppose Laravel, inn your case) you'd want to create a factory implementation that might be called <SensibleName>Factory that takes care of figuring out how to map the posted data to different models, and how their relations should be specified. Under the hood, this factory just uses the model classes' creation facilities to get you where you want to go.
When you would instead automate this process in your model it would be impossible to create the resources independently.
When you would instead automate this process in any single-resource controller that would be non-compliant with the REST paradigm.
With the factory pattern, you explicitly use that class to perform the higher level action, and none of the above concerns apply, not speaking about whether this approach is in accordance with REST at all.
The key takeaway is that the exact same result must still be achievable by performing multiple requests to single-resource endpoints, and your additional /api/sensible-name endpoint just substitutes for the need to call to those multiple endpoints, for the purpose of convenience, when you DO want to create multiple records in a single go.
Note that my statement has little to do with what endpoints to create to fetch nested resources. This SO question has some pretty good conversation as to what is acceptable, and how your specific needs might relate to that.
In the end, it's all about what works for you and your application, and REST and the like are just philosophies that propose to you an approach for similar needs in general web development as well as possible.
The last few days, I have extensively read books and web pages about OOP and MVC in PHP, so that I can become a better programmer. I've come upon a little problem in my understanding of MVC:
Where do I put a mysql_query?
Should I put it in the controller and call a method on a model that returns data based on the provided query? Or should I put it in the model itself? Are both of the options I'm providing total garbage?
Materials on the subject of MVC
You could have listed the books you were reading, because most (if not all) php books, which touch on MVC, are wrong.
If you want to become a better developer, i would recommend for you to start with article by Marting Fowler - GUI Architectures. Followed by book from same author - "Patterns of Enterprise Application Architecture". Then the next step would be for you to research SOLID principles and understand how to write code which follows Law of Demeter. This should cover the basics =]
Can I use MVC with PHP ?
Not really. At least not the classical MVC as it was defined for Smalltalk.
Instead in PHP you have 4 other patterns which aim for the same goal: MVC Model2, MVP, MVVM and HMVC. Again, I am too lazy to write about differences one more time, so I'll just link to an old comment of mine.
What is Model ?
First thing you must understand is that Model in MVC is not a class or an object. It is a layer which contains multitude of classes. Basically model layer is all of the layers combined (though, the second layer there should be called "Domain Object Layer", because it contains "Domain Model Objects"). If you care to read quick summary on what is contained in each part of Model layer, you can try reading this old comment (skip to "side note" section).
The image is taken from Service Layer article on Fowler's site.
What does the Controllers do ?
Controller has one major responsibilities in MVC (I'm gonna talk about Model2 implementation here):
Execute commands on structures from model layer (services or domain objects), which change the state of said structures.
It usually have a secondary responsibility: to bind (or otherwise pass) structures from Model layer to the View, but it becomes a questionable practice, if you follow SRP
Where do I put SQL related code ?
The storage and retrieval of information is handled at the Data Source Layer, and is usually implemented as DataMapper (do not confuse with ORMs, which abuse that name).
Here is how a simplified use of it would look like:
$mapper = $this->mapperFactory->build(Model\Mappers\User::class);
$user = $this->entityFactory->build(Model\Entities\User::class);
$user->setId(42);
$mapper->fetch($user);
if ($user->isBanned() && $user->hasBannExpired()){
$user->setStatus(Model\Mappers\User::STATUS_ACTIVE);
}
$mapper->store($user);
As you see, at no point the Domain Object is even aware, that the information from it was stored. And neither it cases about where you put the data. It could be stored in MySQL or PostgreSQL or some noSQL database. Or maybe pushed to remote REST API. Or maybe the mapper was a mock for testing. All you would need to do, to replace the mapper, is provide this method with different factory.
Also, please see these related posts:
understanding MVC Views in PHP
testable Controllers with dependencies
how should services communicate between each other?
MVC for advanced PHP developers
Model and Entity Classes represents the data and the logic of an application, what many calls business logic. Usually, it’s responsible for:
Storing, deleting, updating the application data. Generally it includes the database operations, but implementing the same operations invoking external web services or APIs is not an unusual at all.
encapsulating the application logic. This is the layer that
should implement all the logic of the application
Here is the MVC Sequence Diagram which shows the flow during a http request:
In this case Model is the best place to implement the code realted to access database.
The model contains the domain objects or data structures that represent the application's state. [wikipedia]. So the model would be the place to make the database call.
In the 'classic' (lack of a better word atm) MVC pattern the view would get the current state from the model.
Don't make the mistake by saying that the model is for accessing the database. It's more than just accessing the database.
For one, don't use mysql_query() and family; they're being deprecated, so consider also learning about PDO and/or mysqli.
The model takes care of data handling; it provides an interface to the controller by which it retrieves and/or stores information. So this would be a primary place where database actions take place.
Update
To answer a question asked by the OP in the comments: "one generic model for the whole db or a model for each table/action?"
Models are meant to abstract away individual tables (although there are models that exclusively handle a single table); for instance, instead of asking for all articles and then query the usernames for the authors you would have one function like this:
function getArticles()
{
// query article table and join with user table to get username
}
How many models you will create largely depends on how big the project is and how inter-related the data is. If you can identify independent groups of data, it's likely that you'd create a model for each group; but this is no hard & fast rule.
Data manipulation can be part of the same model, unless you want a clear separation between read-only and write-only models (I wouldn't know of a situation that warrants this, but who knows).
To go even further, your model should not contain the database access code. This belongs to another layer outside the Model/View/Controller: this is called the persistence layer, which can be implemented using an Object-Relational Mapper such as the popular Doctrine 2 for PHP.
This way, you never touch any (my)SQL code. The persistence layer takes care of this for you.
I really advise you to have a look at a Doctrine tutorial, this is a really professional way to create your applications.
Instead of working with raw data loaded from the database, you create objects that hold your data, and the behavior associated with it.
For example, you might have a User class, such as:
class User
{
protected $id;
protected $name;
protected $privileges;
public function setName($name) { ... }
public function getName() { ... }
public function addPrivilege(Privilege $privilege) { ... }
public function getPrivileges() { ... }
}
You controller will only interact with objects:
class UserController
{
public function testAction()
{
// ...
$user = $em->getRepository('User')->find(123); // load User with id 123
$user->setName('John'); // work with your objects,
echo $user->getName(); // and don't worry about the db!
$em->flush(); // persist your changes
}
}
Behind the scenes, the ORM takes care of all the low-level work of issuing a SELECT query, instantiating your object, detecting modifications to your object, and issuing the necessary UPDATE statement!
I'm using ZF for an MVC application and am massively confused about how my code should be structured.
I've got a procedural application which is basically 1 huge long file with functions for everything I want my app to do.... like: getUsername($id) etc. So now I'm remaking the entire thing in ZF because my current codebase is unworkable, crap and hard to debug.
I'm new to MVC and massively confused about how it should all be laid out, what should talk to what etc. So I know about Views about being templates and Controllers needing to be skinny and that you should have fat models but I'm confused where the logic needs to be.
I'm making a game and there usual objects like.... Users, Villages, Armies, MapSquares, Resources etc.
If I was thinking about it completely by theory I would just say:
1 User Object contains many villages, each village belongs to one square and contains an army (which contains many units).
So what I thought was that my Models should contain no logic, just a list of get and set functions for retrieving the data and that the logic for processing, asking questions should be done inside the Mapper... like:
$villageMapper = new VillageMapper();
// Get village from database using mapper
$village = $villageMapper->getVillage($id, new Village());
When I want to determine say the outcome of two villages attacking one another, where would this be done? Would I do something like:
$outcome = $villageMapper->determineAttackOutcome($village1, $village2);
Or would I have say... a battle object with a bit of logic inside it?
$battle = new Battle();
// Add participants
$battle->addAttacker($village1)->addDefender($village2);
$outcome = $battle->performAttack();
// Save village changes cause of battle
$villageMapper->save($battle->getAttacker());
$villageMapper->save($battle->getDefender());
I have a bunch of DbTable php files, which I guess all the Database code lives in... so my question is: Should my Mapper objects ONLY really be used for things like, getting and saving to the database?
Thanks, Dom
There are many different interpretations of MVC, but this is how I understand it:
Model: Contains virtually all the logic pertaining to a specific item. Each thing that must be modeled (in your case users, villiages, etc) has a model to go with it. The model has functions to get data out and put data in (i.e. getters and setters). The model also does error checking and such and makes sure that nothing conflicting is entered in.
View: Has no logic whatsoever. In a web application, this is literally just the thing that says where to put stuff on the page. In some frameworks you feed a view a model (i.e. ASP.NET MVC3), in other frameworks (like Savant3 for php) it can be fed anything. The controller generally feeds the view, but the if the view is given a model it just reads from the model and doesn't write to it.
Controller: Controls the interaction between the user and the model. When the user does something, the controller translates that into things that the model must do. For example, if you say to the program "Please move my character 6 spaces north", the controller will say "Is there anything to run in to 6 spaces north of here?" and if it sees the spot is clear it tells the character model "Move yourself 6 spaces north". After doing that, it will send data to the view about whatever should be displayed as a result of that. Most of the actual logic implemented in a controller should be user-model instead of model-model. The interactions between models can be either taken care of by methods in individual models or other models that encapsulate some sort of behavior or interaction.
So, on to your implementation:
I would make a battle object (which is a model) whose constructor takes two villages or whatever is fighting. It would have a method called execute or doBattle or something that the controller would call and then the battle object would perform its logic to decide the outcome and update the status of the combatants (i.e. lowering hp, giving experience, etc). It would return to the controller the result so that the controller knows what to do (i.e. if the controller needs to forget about a model because it died, it would tell it that). This return value could also be the thing sent to the view to tell the outcome of the battle.
Some of your models (such as user, village, etc) would be kept in the database and so the model would know how to map itself to that database (or it would talk to another layer that knows how to map it) and also take care the exact implementation of updating the database and stuff (the controller would call the actual method to "save", but the model would be the only thing knowing what goes on behind the scenes). Other models (such as battle) don't need to exist in the database since they are just logic encapsulating some interaction.
Having a fat model means then nearly all of the logic exists within the model.
Some sugesstions...
If you are doing Domain Driven Design (http://en.wikipedia.org/wiki/Domain-driven_design) your village object could be an aggregate root that manages the business logic of that village.
A battle could also be an aggregate root that consists of two (or more) village objects, or a service that takes in two village objects and returns an "outcome" object. You could also do something along the lines of $village->attack($anotherVillage) that could return a battle object that you may then persist.
I would suggest following Domain Driven Design and the Repository pattern when it comes to creating and persisting these business objects http://msdn.microsoft.com/en-us/library/ff649690.aspx
Datamapper should only be used for storing and retrieving data from your database and mapping that data to your domain objects (Users, Villages, Armies, MapSquares).
You could put your logic inside your domain objects, but I like to use a service layer instead.
In your controller your would do something like:
function attackAction() {
$gameService->doVillageBattle($villageId1,$villageId2);
}
GameService would look like:
doVillageBattle($villageId1,$villageId2) {
$village1 = villageService->getById( $villageId1);
$village2 = villageService->getById( $villageId2);
if ($village1->getStrength() > $village2->getStrength()) {
$village1->winBattle();
$village2->looseBattle();
$villageService->save($village1);
$villageService->save($village2);
}
}
And finally VillageService would have:
function save( $village ) {
villageMapper->save( $village );
}
So controllers talk to services only, and services talk to each other or to datamappers logically associated with them. Services host most of the "business logic" and are database independent. Datamappers are independent of services & controllers ofcourse.
Unless you count QBASIC back when I was a kid, I learned to program in the object oriented paradigm a half-decade ago in university, so I understand how it works. I have difficulty, however, implementing it in my large, database-driven PHP applications, because everything is re-initialized on each page load. The only true persistence is the database, but pulling all the data from the database and reconstructing all the objects on every page load sounds like a lot of overhead for not much benefit, as I'll just have to do it all over again on next page load.
Additionally, I run into these sorts of problems when I try to re-factor an application (third attempt now) to OO:
A class called "Person" exists, and it contains a variety of properties. One of the extensions of that class, "Player", contains a "parent" property, of the type "Player". Initially, none of the players start with any parents, so they would all be initialized with that field as NULL. Over time, however, parents would be added to the Players properties, and would reference other Player objects that already exist.
In PHP, however, it's inevitable that I would have to rebuild the class structure with Players already having parents. In such a case, if I instantiate a Player who has as a parent a Player that hasn't been instantiated yet - I have a problem.
Is it necessary to reduce the scope of OO programming when dealing with PHP?
You're confusing OOP concepts, with concepts about HTTP and persistence.
Your question isn't really about OOP at all- it's about persisting OOP data across multiple HTTP requests.
PHP doesn't automatically persist objects across HTTP requests- it's left up to you to take care of that (in your case, doing just as you said: "pulling all the data from the database and reconstructing all the objects on every page load").
Is it necessary to reduce the scope of OO programming when dealing with PHP?
No. You just need to use lazy loading to instantiate parent player only if it becomes necessary.
Class Player {
protected $id;
protected $name;
protected $parentId;
protected $parent;
public static function getById($id) {
// fetch row from db where primary key = $id
// instantiate Player populated with data returned from db
}
public function getParentPlayer() {
if ($this->parentId) {
$this->parent or $this->parent = Player::getById($this->parentId);
return $this->parent;
}
return new Player(); // or null if you will
}
}
This way if you intantiate player id 40:
$john = Player::getById(40);
It does not have the $parent property populated. Only upon call to getParentPlayer() it is being loaded and stored under that property.
$joe = $john->getParentPlayer();
That is of course only if $parentId is pointing to non-NULL.
Update: to solve problem of duplicate instances stored in protected property when two or more players share single parent, static cache can be used:
protected static $cache = array();
public static function getById($id) {
if (array_key_exists($id, self::$cache)) {
return self::$cache[$id];
}
// fetch row from db where primary key = $id
// instantiate Player populated with data returned from db
self::$cache[$id] = ... // newly created instance
// return instance
}
If you expect to access significant number of parents on every request, it may be feasible to select all records from database at once and store them in another static pool.
Items not being created by means of parents is indeed something that is tricky. You could do something like, ID referencing and build a PlayerManager that does the linking for you. By means of RUID's (Runtime Unique ID's). But of course, you would like to have the parents be created first.
So when creating something like an OO structure of your database, which I would encourage if you want to do some extra manipulations on it besides printing. It is doable to create a player from your DB and then, if it has a parent, create the parent as you would do normally. When arriving at the parent in your while-loop. You can just say, no it is already created. Use a Player-manager class for this, which holds your Players. So it can check if Players (and thus parents) are already there.
So you get a bit of a different way of walking through your DB, instead of just doing it linear.
As for: is it necessary to do so. I actually don't know that much about it myself. It seems, as far as I've seen on the web, that PHP classes are mostly used to created one object that can do smart things (like a DOMDocument).
But do you really have to convert your DB table to objects? It depends on your type of application. If printing is what you want, it doesn't seem logical. If some big manipulation with a lot of calls to the objects (or normally to the table), I maybe would like to see a nice OO programmed structure.
OOP programming in PHP is for me more a way of having a good maintainability and a good architecture (composition, factories, component based programing, etc ).
For sure you'll need to rethink some Design Patterns used in persitent envirronments. Pools of objects, etc. And of course some Design Patterns as still completly good in PHP used in short-term module in apache: Singleton, Factory, Adapter, Interfaces, Lazy loading etc.
About the persitence problem there're several solutions. Of course database storage. But you have as well the session storage and application caches (like memcached or apc). You can store serialized objects in such caches. You'll just need a good autoloader to get the classes loaded (and a good opcode to avoid re-interpreting the sources at every requests).
Some objects are really heavy to load and build, we can think for example of an ACL object, loading roles, ressources, default policy, exception rules, maybe even compling some of theses rules. Once you've got it it would be a desaster to rebuild this object at every request. You should really study the way to store/load this finished object somewhere to limit his load time (avoiding SQL requests and build time). Once built it's certainly an object that could have a long life, like 1hour.
The only objects that you cannot store as serialized strings are in fact the one which depends shortly of data updates by concurrent requests. Some websites does not even need to really care about it, accuracy of data is not the same in a public website publishing news and in a financial accouting app. If your application can handle pre-build serialized objects you can see the serialize-storage-load-unserialize as a simple overhead in the framework :-) But effectivly, share nothing, no object listening to all concurrent requests, no write operation on an object shared with a parallel request until this object (or related data) is stored somewhere (and read). Take it as a challenge!
I am fairly new to using separate layers for the business logic (Domain) and database access logic, but in the course of working things out I've come across a problem to which I still feel I haven't found a great solution.
Clarification My existing solution uses Data Mappers to deal with the database interactions directly. However, as I've further investigated this issue many people have suggested that the Domain layer should not directly communicate with nor contain the Data Mappers that actually perform the database interaction. This is why I placed the Repository objects between the Domain and the necessary Data Mappers but this doesn't feel quite natural or correct. So the real question is what layer naturally exists to handle communication between the Domain and the Data Mappers? Any examples of how to structure it would be appreciated.
For example:
How do I properly handle retrieving a collection of domain objects within the context of another domain object?
How do I force the insertion of a single domain object or collection of objects based on an action performed against another object. The case I'm facing currently is that when a Person is attached to a Campaign, then I need to insert all of the Events that need to be executed for that Person for that Campaign.
There is a distinction between a domain model and the implementation of it. Just because your model shows a relationship Person ---> Campaign ---> Event does not mean that you have to implement it in this way. IOW, your model shows your analysis and design in an object-oriented way, yet you implement that model in OOP which is limited in how well it can replicate that model in code.
Consider the following.
A Person is not defined by its ownership of a Campaign, so campaign can be left out of its knowledge responsibities. On the other hand, a Campaign is defined by the Events that occur as part of its execution, so it is fair to have a collection of events within a campaign. The point that I am making is that each class should have just enough behaviour and knowledge to make it whole.
As for communication between the domain and the persistence layers, consider them as two very distinct systems that are not concerned with the other. All each of them knows is what its responsiblities are and what announcements it makes. For example, the persistence layer knows how to persist data passed to it and to announce that data have been saved. However, the persistence layer does not necessarily need to understand the domain objects. Similarly, the domain layer understands Person, Campaign, and Event but knows nothing about persistence.
The implication of the above is that the domain layer needs to be a whole by itself and should not be dependent on the persistence layer for its data. However, it still needs to be supplied with data to perform its responsibilities. That data can come from either the user interface or the database and is passed to it via a third-party that knows about both domain and persistence layers.
So, in code (pseudo-C#)...
namespace DomainLayer
{
interface IDomainListener
{
void PersonCreated(Person person);
}
class Person
{
private string name;
public Person(string name)
{
this.name = name;
}
public string Name
{
get { return name; }
}
}
class Domain
{
private IDomainListener listener;
public Domain(IDomainListener listener) {
this.listener = listener;
}
public void CreatePerson(string name) {
Person person = new Person(name);
listener.PersonCreated(person);
}
}
}
namespace PersistenceLayer
{
interface IPersistenceListener
{
void PersonDataSaved(int id, object data);
}
class Persistence
{
private IPersistenceListener listener;
public Persistence(IPersistenceListener listener)
{
this.listener = listener;
}
public void SaveData(object data)
{
int id = ...; // save data and return identifier
listener.DataSaved(id, data);
}
}
}
namespace MyApplication
{
class MyController : IDomainListener, IPersistenceListener
{
public void CreatePersonButton_Clicked()
{
Domain domain = new Domain(this);
domain.CreatePerson(NameTextbox.Text);
}
public void PersonCreated(Person person)
{
Persistence persistence = new Persistence(this);
persistence.SavePersonData(person.Name);
}
public void DataSaved(int id, object data)
{
// display data on UI
}
}
}
As you can see, the namespaces represent the different tiers. The XYZListener interfaces define the announcements that are made by the XYZ tier. Any other tiers that are interested in these announcements and will respond to them need to implement these interfaces, as does our MyApplication tier.
When the "create button" is clicked, the controller creates the Domain facade object for the domain layer and registers itself as a listener. It then calls the CreatePerson method which instantiates a Person then announces that this has been done, passing the new instance. The controller responds to this announcement in the PersonCreated implementation where it spawns a facade of the persistence layer and registers itself as the listener again. It then calls the SaveData method whichannounces DataSaved when completed. The implementation of that method then displays the data on the UI.
As you can see, the domain layer and the persistence layer are each aware of only tmemselves and are not concerned with the responsibilities of the other. It is the application logic, manifested here as the controller, that wires the two together.
Back to your specific problem, you could have a method FindPerson on the persistence, which would announce PersonFound(int id). The response by the controller would be to call the persistence layer to retrieve data about campaign and events, then call the domain layer with that data to build the Person.
Sorry for the long answer...
Gabriel, this is called the "impedance matching problem." There are many solutions around, from heavyweight ones like J2EE entity beans to Ruby ActiveRecord to simply coding a hand connection.
Update
Okay, well, its hard to see exactly how to attack this without a lot more information, but here's the basic approach.
Any of these sorts of architectural issues are driven by non-functional requirements like performance; in addition, there is a correctness issue here, in that you want to make sure updates are done in the correct order. So, you're going to need to think about the workload, which is to say the pattern of usage in real-world application. With that in mind, you basically have a couple of issues: first, the base data types in your application may not map correctly to the data base (eg, what's a VARCHAR property represented as in your code?), and second your domain model may not map cleanly to your database model.
What you would like is to have the database and the dmain model work out so that one instance of a domain object is exactly a row of a table in your database model; in large-scale applications you can rarely do this because of either performance constraints or constraints imposed by a pre-existing database model.
Now, if you completely control your database model, it simplifies things somewhat, because then you can make your database model more closely resemble the domain. This might mean the database model is somewhat denormalized, but if so, you can (depending on your database) handle that with views, or just not have a completely normalized database. Normalization is a useful theoretical construct, but that doesn't mean you can't relax it in a real system.
If you don't completely control your database model, then you need a layer of objects that make the mapping. You've got a bunch of options to choose from in implementing that: you can build views or denormalized tables in the database, you can build intermediate objects, or you can do some of both, or even have several steps of both (ie, an intermediate object that accesses a denormalizaed table.)
At that point, though, you run into issues with "don't repeat yourself" and "do the simplest thing that will possibly work." Think about what is most likely to change? Your domain model? If you've got a strong domain model, that's less likely --- the business changes relatively rarely. The exact representation of data in the database? A little more common. Or, most commonly, the exact patterns of use (like discovering a need to handle concurrent updates.) So, when you think about that, what do you need to do to make it as easy as possible to deal with the most common changes.
I realize this isn't giving you very precise instructions, but I don't think we can offer precise instructions without knowing a whole lot about your applicaiton. But then I also kind of get the impression you're wondering about what the "right" way of handling this would be, while you are already working with something that more or less does the job. So, I'd end up by asking "what are you unhappy with now?" and "How would you like to solve that?"
Many systems employ an independent data layer to handle persistence to and from a database. There are several models for the organization of such a layer. Some use a sort of factory-like implementation, others employ a one-to-one mapping with one data layer class per domain class.
The model for the data layer often depends on style and preference. What is important is separating the persistence layer from the domain layer. I believe there are tools out there that will help you generate this layer, but my PHP knowledge is thin so I can't name any specifically for PHP.
I would look at the data abstraction layers used by PHPCake and Symfony.