How to represent an object and map between different sources/locations - php

I will be building a system where a particular object will originate from a web service (SOAP based). It will then be displayed on a web page (via PHP). Under certain circumstances we'll store a copy with some additional information in a local MySQL database. And from there it will be batch processed into Salesforce CRM (again via PHP). We may also subsequently pull the object out of Salesforce for display online. So alot going on. For the most part the object is the same with each subsequent node in the system likely adding a couple of fields specific to it, unique ids mainly.
I'd initially toyed with the idea of encapsulating all the necessary functionality into the one class in PHP which would deal with reading and writing from each of the appropriate sources. This felt like it was over complicating the class, and not a good approach.
I then looked at having just a container class, with no real functionality attached beyond getters and setters. Then creating separate functionality outside of this to deal with the reading and writing between the different sources, simple enough code although tedious to map between all the different field names across the different sources. There is probably a design pattern or two that apply here, but I'm not familiar with them. Any and all suggestions on how to approach this appreciated.

What you are looking is Adapter pattern. You can keep your existing code till you completely change all the classes.

I'd suggest to use a composite memento serializable into XML.

I think they may be several ways to handle that. #EGL 2-101 adapter idea is one way to do it.
Basically, you have several sources, which in O.O. jargon, are different objects. But, you want to treated like if they where a single object.
You may want to make a single class for each source, test the "connection", as if each case was the only way you where going to work with. When you have several of that classes, try to make all classes share some interface, methods or properties:
class AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class SOAPObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class MYSQLObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
class SalesObject extends AnyConnection
{
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
Later, use a single class to wrap to all of these source classes.
class AnyObject extends AnyConnection
{
$mySOAPObject;
$myMYSQLObject;
$mySalesObject;
public function __construct() {
// ...
}
public function read() {
// ...
}
} // class
Later, add the code, to select which "connection" you want.

Why not separate data and operations?
Contain the core information into a class C. When web services sends this class, it is encompassed in an object of some class W. The web service pulls C and sends it to persistence layer, which creates and stores P that internally contains C, et.c.,
Akin to how data flows over a TCP/IP stack...

The way I see this after thinking about it a bit would be pretty much a class to play with your object and then serialize it.
I'd probably use something like this:
<?php
class MyObject
{
protected $_data;
public function __construct($serializedObject = null) {
if(!is_null($serializedObject)) {
$this->_data = json_decode($serializedObject);
}
}
public function __get($key) {
return $this->_data[$key];
}
/* setter and other things you need */
public function encode() {
return json_encode($this->_data);
}
public function __toString() {
return $this->encode();
}
}
Then just use it to pass it serialized to your different web services.
I think JSON would do a pretty good job on this one, because you can easily unserialize it fast in so many programming languages and it's so much lighter than XML.

DataMapper pattern is that what you're looking for.
You can have one mapper for each storage mechanism that you use and use them all with one object that represent data to business logic.

Is seems your problem is more of an architectural / design decision that pure implementation detail. (I haven't done PHP for a long while and do not know salesforce but other CRM systems)
I believe the technique/pattern that will work for you is the use of a staging area. This helps especially if you have changing integration needs and also when your source data looks different from your system model or when you have different sources to integrate from. Thus, you import into the staging area and then from the staging into your system. At each place you naturally have to map (can use metadata) and maybe transform/translate data. There will be initial effort to build this, but once it's done the step from staging to your system stays quite static/stable.
Using meta data mapping can address flexibility concerns but adds a bit of complexity on implementation. It all depends on the skills and time you have at hand for your project.

I would not have any association between the objects at all. They are used for different purposes but looks similar. period.
In .NET we use a library called automapper to copy information between different classes (like a business object and a DTO). You can build something similar in PHP, either by using get_object_vars or the reflection API.
myCopyApi.copy($myDTO, $myBO);

Say you retrieve a Car from the webservice. You can store it in a WebserviceCar, which has a property car.
Now, if you want to store that Car in the database, put it in a DatabaseCar, which also has a property car. If you want to put it in Salesforce, put it in a SalesforceCar object, which has a property car.
This way, you have one object which has the common fields and several objects which have storage-specific information.

Assuming that you are thinking about storing the actual object (serialized,encoded or whatever) in a field in the database: From my point of view the object it is never the same in two applications, as business-wise, it serves different purposes. Doing this is a kind of "cutting short" in a case where is no room for "cutting short".
Remember that mainly class represents a "category of objects" which all share same properties and behaviours. So let each application use it's own class as their purpose requires it. What can be created although is, as others suggested and as you thought, the creation of an Adapter or Factory which can be used in all the implied applications as it serves the same business purposes "translation" of objects.
Adapter pattern
Factory pattern

Related

PHP MVC - Model needs to access data from another model

I have built a small PHP MVC framework and just want to clarify the best way to get data from one model into another. For example:
I have a Users_model that contains a method called get_users().
I also have Communications_model that needs to get specific or all user data and as such needs to access the get_users() method from the Users_model.
Is it best practice to:
a) Instantiate the Users_model in a controller and pass the data from the get_users() method into the Communications_model?
b) Instantiate the Users_model inside the Communications_model and run get_users() from there, so it can be accessed directly?
c) Another way?
Many thanks for any help.
It depends of your motive behind this.
If you want effect on result, then using well know library, like Doctrine etc. should be your choice.
If you want to learn design patterns, then you should get read about ActiveRecord or DataMapper + Repository patterns. Then implements both and check out.
If you want your code, this way - ORM should represent relations of data, then you should ask what it more important? If you menage communication (bus, train), then user can be there assigned and getting users from communication is OK. If user have communication (like car), then relation is reversed.
All depends, what is you motive behind this. Using library, like Doctrine, could you help you running you application. If you want learn design patterns, then check out both options to get some experience.
What you call "users model" is a repository. And what you call "communication model" looks like a service.
Your communication service should have the user repository passed in constructor as a dependency.
I honestly think, that a huge part of your confusion is that you try to call all of those things "models". Those classes are not part of the same layer. You migth find this answer to be useful.
All are possible ways but what I usually do is, whenever there is any function that I think would be reused a number of times by a number of objects, I declare it as static.
It would save the effort of playing with object declaration and would be easily accessible by ClassName::function();
Again, it's a design choice, usually objects are declared right there in the controller and used as per the need but just to save declaration of objects again and again I follow the approach of declaring function static.
The simple principle here is using the __construct() (constructor) to build the object with the relevant properties from the Database. The User Model will have a static function (therefore accessible through any scope) to create an array of instanced objects by simply passing the model data through a new self() which returns the instance.
The concept is you end up with an array of User_Model instances each being a build of the Database columns to properties. All that's left is to create the Database Model and the functions to retrieve the columns and data.
class Communications_Model {
private $_all_users;
public function getUsers() {
$this->_all_users = Users_Model::loadAllUsers();
}
}
class Users_Model {
private $_example_property;
public function __construct($user_id) {
$data = SomeDatabaseModel::getConnection()->loadUserFromDatabase((int)$user_id);
$this->_example_property = $data['example_column'];
}
public static function loadAllUsers() {
$users = array();
foreach(SomeDataModel::getConnection()->loadAllUsers() as $data) {
$users[] = new self($data['user_id']);
}
return $users;
}
}
Of course, now, you have a $_all_users; property that has an array of instanced User Models containing the data.

Does this break open closed principle

I am attempting to create a factory. I want the client to send a code to the create method, which will be used to instantiate a class that is used to process that type of 'thing'.
The list of codes are a member of the class, since they should never change. But, to make it more testable i have added a setter for the codeMap array.
Does this break the open closed principle and if so, how to make this testable correctly?
<?php
class My_ThingFactory
{
/**
* #var array
*/
private $codeMap = array(
'A111' => 'My_Thing_ConcreteA'
);
public function create($code)
{
if (isset($this->codeMap[$code])) {
return new $this->codeMap[$code];
}
}
public function setCodeMap(array $codeMap)
{
$this->codeMap = $codeMap;
}
}
The Open/Closed principle has to do with extending some code to add functionality without modifying the core behavior (i.e. by not editing the source code) of your class. Your class keeps its internals to itself and provides clear public interfaces to interact with them. From this perspective, no you have not broken open/closed principle. At least not at face value.
However, that said, I also got the impression from your question that you are wondering if having a setter for your private $codeMap array breaks the principle. It doesn't directly, but the implementation also makes it attractive to modify if another developer wants more fine tuned access to the $codeMap array. Basically, the only way to update this array on the fly is to wipe it out and reset it with setCodeMap(). You are not providing a mechanism to add a single code to the map. As soon as you find yourself needing more granular access to this map, you will also find yourself violating the open/closed principle.
Consider this, let's say another developer is using your code and the $codeMap array is 20 or 30 elements strong; they must hack your core code to provide better access to that array. Since there is not way to add a single code, they must create a new array to pass to setCodeMap() that consists of the current $codeMap array plus any additional elements they wish to add. There isn't another way (besides hardcoding the original array) to do this without opening up the My_ThingFactory and adding something like:
public function getCodeMap()
{
return $this->codeMap;
}
Then in their extended class they could do something like:
class AnotherThingFactory extends My_ThingFactory
{
public function addCodes(array $newCodes)
{
$this->setCodeMap(array_merge($this->getCodeMap(), $newCodes));
}
}
But again, this is only possible by going into your class and adding the needed functionality before, which does break the open/closed principle. You could also rectify this by simply making the $codeMap property protected and then an extending class can do what they need to without hacking your code. The extending class also then has the onus of ensuring that they are manipulating it correctly.
So to answer the open/closed question: if you are intending to keep the $codeMap locked down by design and don't intend for it to be used in alternate way then you are fine. But as I said above as soon as you need better control of the $codeMap array, you will need to violate the principle to do so. My suggestion would be to brainstorm how much management of that factory you want built in to your class and make it part of the class core functionality.
As for testing, I don't see why you couldn't test this code as it is. You can set your code map and then test for the corresponding instance that was returned with the create() method.
class FactoryTest extends PHPUnit_Framework_TestCase
{
private $factory;
public function setUp()
{
$this->factory = new My_ThingFactory();
}
public function tearDown()
{
$this->factory = null;
}
public function testMadeConcreteA()
{
$this->assertInstanceOf('My_Thing_ConcreteA', $this->factory->create('A111'));
}
public function testMadeStealthBomber()
{
$this->factory->setCodeMap(array('B-52', 'StealthBomber')); //Assume the class exists.
$this->assertInstanceOf('StealthBomber', $this->factory->create('B-52'));
}
public function testDidntMakeSquat()
{
$this->assertNotInstanceOf('My_Thing_ConcreteA', $this->factory->create('Nada'));
}
}
The open-closed principle is not universal. You need to make an assumption about what is likely to change (the open part) and what is not (the closed part).
Since you're using a factory, the closed part is the create service (factories make this part closed). The open part is the things the factory is going to create. A factory allows extending those things later.
A small but important point is that your pattern is not a GoF factory, but rather a Simple Factory. So, it's perhaps not the strongest form of Factory for exploiting the open-closed principle. That is, if you add new stuff to create, you have to modify the class (the $codeMap array).
What stands out in your question is that you seem to contradict the principle of openness when you say:
The list of codes are a member of the class, since they should never change.
In my mind, if you're using a factory, the list of codes is expected to change.
As for your set function, it's a public method, and so by definition is closed (else you shouldn't reveal it). On the other hand, you're exposing details of the implementation (as mentioned in Crackertastic's answer). You might be concerned more about violating encapsulation with this method.
I think an easier solution (although I'm not sure about it in PHP) is to initialize your factory with a $codeArray that's been created by another class. I think this is what Kamal Wickamanayake refers to in his comment on your question. Another solution is a service (closed) to add/delete elements (which boil down to adding new entries into your $codeArray but in a hidden way).

PHP OO Design: extend static class or instance class?

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I have an application which defines certain actions on common object types.
For example, you can have forum post and images. For each forum post and image you can do the following actions: recommend, comment, rate.
I have currently defined a static class
class CoreObjectUtil
{
protected static $_objObjKey = null;
protected static $_objTypeKey = null;
public static function getComments (...) {...}
public static function getCommentsArray (...) {...}
public static function getRatings (...) {...}
public static function getRatingsArray (...) {...}
}
which is then subclassed like this
class ForumPostUtil extends CoreObjectUtil
{
protected static $_objObjKey = 'forumpost';
protected static $_objTypeKey = 'FP';
}
to provide the relevant functionality for forum posts. The 2 parameters suffice to let the generic code in CoreObjectUtil know what to do for each object type for which these functions are applicable.
To use these functions, I am calling the selectPostProcess() class in my instance classes like this:
public function selectPostProcess ($data)
{
$data = ForumPostUtil::mergeRatings ($data);
$data = ForumPostUtil::mergeComments ($data);
...
}
This works well and keeps the main code centralized in the CoreObjectUtil class with its subclasses providing the data setup to let the code in CoreObjectUtil know what to do.
An alternative approach would be to move the code from CoreObjectUtil into a base instance class which is then inherited in my instance classes. So rather than calling static methods from CoreObjectUtil I would be doing method calls like $this->getComments().
Either approach would work just fine from a functionality type point of view. I'm wondering however what ObjectOriented design guidelines and experienced ObjectOriented developers think of these two approaches. Which way of doing this is preferable and why?
I would appreciate any thoughts/insights on this matter. I can code either way without problem, but I'm having a tough time deciding which route to take.
That code you have now is, I think, the most procedural approach ever posing as OOP i.e what you have now is at the opposite side of OOP. Using the class keyword doesn't make it OOP.
First of all, you should forget about static, it's not that it's bad ot use but it's so easily abused that you really have to try first if the functionality can belong to an object modelling a domain concept (in your case forum related). Only if it doesn't make sense this way, you'll have it as a static method somewhere in a utility class.
Truth be told you have to redesign yur app around the OOP mindset, that is to define classes with behaviour which model a specific concept or process and which have only one responsaiblity. More over you should not mix things like business objects (object which model the forum concepts) with persistence concerns i.e don't put in the same object business functionality and database access. Use a separate class for accessing storage.
Use the Repository pattern to separate business layer from the persistence layer. Try not to mix together create/update functionality with querying IF it complicates things. Use a separate read model specifically for querying in that case.
The code you show us is about querying. You can have a simple DAO/Repository (call it what you want in this case) like this
class ThreadViewData
{
public $Id ;
public $Title;
public $Comments; //etc
}
class ThreadsQueryRepository
{
//we inject the db access object , this helps with testing
function _construct($db) { }
public function GetThread($id){ } //this returns a ThreadViewData
}
The postPRocess functionality is a service that can Merge Ratings and Comments. But maybe the merge functionality is more suitable to the Rating and Comment objects. I don't know the domain to actually give a valid suggestion.
Point is, you have to think in objects not in functions and right now all you have is functions.

PHP + MVC - my domain model is confused

I'm building a web application that needs to be able to write data to either a mysql db or an xml file, depending on the online status of the application.
In my model, I have a super class (Dao is data access object)...
abstract class Dao {
static function getInstance($online_status) {
if $online_status = 'online' {
return new DaoMySQL;
} else {
return new DaoXML;
}
}
abstract function dao_select();
abstract function dao_insert();
abstract function dao_update();
abstract function dao_delete();
}
Now, here is the part I'm confused about. I have a domain model/entity class that selects the appropriate Dao using:
$this->dao = Dao::getInstance($online_status);
So, now I have the correct data access object selected. But, the problem is I still two implementations of dao_select() and the other functions. Now, the main implementations are in the respective classes DaoMySQL and DaoXML, but dao_select() in each of those classes require different things. i.e. the DaoMySQL version needs two parameters, $table and $where_statement. DaoXML (which I haven't implemented) will need the element name, and maybe another argument, I don't know.
So, in my domain model class, after calling
$this->dao = Dao::getInstance($online_status);
is this where I need to include two separate local implementations (pertaining to the domain model/entity class only) of dao_select(), or this wrong? It just seems like I'm taking the elegance out of the process by doing something like this:
class EntityModel {
$this->dao = Dao::getInstance($online_status);
if($this->dao->type = 'mysql') {
$result = $this->dao->dao_select($table, $where);
} else {
$result = $this->dao->dao_select($xml_params);
}
}
I feel like I'm taking the simplicity out of the system... Does this approach make sense, or is there a better one?
You are doing it wrong.
Few notes to begin with:
in OOP the extends statement signifies is a relationship. Which means that, while class Duck extends Bird is all fine, writing class User extends Table is NOT.
in MVC the Model is not a class or an instance of a class. Instead it is a layer of application, mostly made of two types of elements:
domain objects: containing domain business rules and logic
data access structures: usually datamapper dealing with storage and retrieval of information
I would argue, that the third significant part of Model layer are services. But there are options on whether it is part-of or above Model.
Currently what you are trying to do is forcing a ActiveRecord (which is fine for small things, but as project grows, it becomes a burden on architecture .. which is what you are face with now) patterns to work with dynamic data sources. And to do so you are resorting to procedural calls.
Anyway, the point is that you should inject your DAO instance into your Domain Objects (what you calls "models"). And you should leave the creating of your DAO to a separate factory instance, which would be responsible for initializing them and providing them with data source (instance of PDO or file path). This way you can, not only separate the responsibilities, but also swap the storage destination "on fly".
To learn more you should investigate what is dependency injection. Here are few video that might help:
Don't Look For Things!
Global State and Singletons

PHP Structure - Interfaces and stdClass vars

I'm building a class to handle Paypal IPNs as part of a project, and since I already know i'm going to need to use it again in at least two more upcoming jobs - I want to make sure I structure it in a way that will allow me to re-use it without having to recode the class - I just want to have to handle changes in the business logic.
The first part of the question is re. interfaces. I haven't quite grasped their usefulness and when/where to deploy them. If I have my class file ("class.paypal-ipn.php"), do I implement the interface in that file?
Here's what i'm working with so far (the function list is incomplete but its just for illustration):
CLASS.PAYPAL-IPN-BASE.PHP
interface ipn_interface {
//Database Functions
// Actual queries should come from a project-specific business logic class
// so that this class is reusable.
public function getDatabaseConnection();
public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb");
public function dbQuery($SQL);
//Logging Functions
public function writeLog($logMessage);
public function dumpLogToDatabase();
public function dumpLogToEmail();
public function dumpLogToFile();
//Business Logic Functions
private function getTransaction($transactionID);
//Misc Functions
public function terminate();
}
class paypal_ipn_base {
//nothing to do with business logic here.
public function getDatabaseConnection() {
}
public function setDatabaseVars($host="localhost",$user="root",$password="",$db="mydb") {
}
public function dbQuery($SQL) {
}
}
CLASS.PAYPAL-IPN.PHP
final class paypal_ipn extends paypal_ipn_base implements ipn_interface {
//business logic specific to each project here
private function getTransaction($transactionID) {
$SQL = "SELECT stuff FROM table";
$QRY = this->dbQuery($SQL);
//turn the specific project related stuff into something generic
return $generic_stuff; //to be handled by the base class again.
}
}
Usage
In this project:
Require the class files for both the base, and the business logic class.
Instatiate *paypal_ipn*
Write code
In other projects:
Copy over the base IPN class
Edit/rewrite the business logic class *paypal_ipn* within the constraints of the interface.
Instantiate *paypal_ipn*
Write code
So as you can see i'm literally just using it to define groups of related functions and add comments. It makes it easier to read, but of what (if any) other benefit is it to me - is it so that I can pull the extender and the base class together and force errors if something is missing?
stdClass Question
The second part of the question is building on the readability aspect. Within the class itself there is an ever increasing number of stored variables, some are set in the constructor, some by other functions - they relate to things such as holding the database connection vars (and the connection resource itself), whether the code should run in test mode, the settings for logging and the log itself, and so on...
I had started to just build them as per usual (again, below incomplete & for illustration):
$this->dbConnection = false;
$this->dbHost = "";
$this->dbUser = "";
$this->enableLogging = true;
$this->sendLogByEmail = true;
$this->sendLogTo = "user#domain.com";
But then I figured that the ever growing list could do with some structure, so I adapted it to:
$this->database->connection = false;
$this->database->host = "";
$this->database->user = "";
$this->logging->enable = true;
$this->logging->sendByEmail = true;
$this->logging->emailTo = "user#domain.com";
Which gives me a much easier to read list of variables when I dump the entire class out as I code & test.
Once complete, I then plan to write a project specific extension to the generic class where i'll keep the actual SQL for the queries - as from one project to another, Paypal's IPN procedure and logic won't change - but each project's database structure will, so an extention to the class will sanitize everything back into a single format, so the base class doesn't have to worry about it and will never need to change once written.
So all in all just a sanity check - before I go too far down this road, does it seem like the right approach?
if you are using a class autoloader, which I highly recommend, you would not want to keep the interface and the class in the same file so that the interface can autoload without needing to first load this one class that implements it.
For more info on autoloading:
http://php.net/manual/en/language.oop5.autoload.php
another thing you may want to consider is that a given class may impliment multiple interfaces, and multiple classes may implement the same interface.
interfaces are primarily used for various design patterns, to enforce rules, and to decouple a class from any dependent classes. when you decouple a class from its dependencies, it makes it much easier to modify code at a later time.
for instance, let's say you have a class A that takes in another class B as an argument, and this class is spread throughout your code. you want to enforce that only a class with a specific subset of methods can be accepted as this argument, but you do not want to limit the input to one concrete class and it's decendants. in the future, you may write an entirely different class that does not extend class B, but would be useful as an input for class A. this is why you would use an interface. it is a reusable contract between classes.
some would argue that since PHP is a dynamic language, interfaces are an unecessary complication, and that duck typing may be used instead. I find in large multi-user code bases however, that interfaces can save a lot of time, letting you know more about how one class uses another, without having to study the code in depth.
if you find yourself with a large list of variables that you have to pass around between objects or functions, they often do end up deserving a class of their own, but each case is different.
-- dependency injection example --
class A implements AInterface {
public function foo($some_var) {}
}
interface AInterface {
public function foo($some_var);
}
class B {
protected $localProperty;
// inject into the constructer. usually used if the object is saved in a property and used throughout the class
public function __construct(AInterface $a_object) {
$this->localProperty = $a_object;
}
// inject into a method. usually used if the object is only needed for this particular method
public function someMethod(AInterface $a_object) {
$a_object->foo('some_var');
}
}
you can now see that you can write another class that impliments a foo method (and the AInterface) and use that within class B as well.
as a real world example (used often), say you have a database class with particular methods that interact with the database (getRecord, deleteRecord). now lets say at a later time you find a reason to switch database rdbms. you now need to use entirely different SQL statements to accomplish the same goals, but since you used an interface for your type hinting, you can simply create a new class that impliments that interface, but impliments those same methods in entirely different ways as it interacts with a different rdbms. when creating this new class, you will know exactly what methods need to be written for this new class in order to fit into the same objects that need to use a database object. if you use a container class that you use to create objects and inject them into other objects, you would not need to change too much application code in order to switch databases classes, and therefore switch database rdbms. you could even use a factory class, which could limit your changes to one line of code to make this type of change (in theory).

Categories