I have a class that performs database operations and returns results (array, true, false). And I have an another class that creates JSON string by using this class in its constructor.
Can we say this class is an Adapter? Or simply wrapper or ...
Class Db
{
public function getRows($params)
{
//...
}
}
Class DbAdapter
{
private $_dbh;
public function __construct($dbh)
{
$this->_dbh = $dbh;
}
public function getJson()
{
return '{"key": "foo", "key2": ' . json_encode($this->_dbh->getRows($params)) . '}';
}
}
Thanks
Id say its more of Decorator... http://en.wikipedia.org/wiki/Decorator_pattern
From: http://www.fluffycat.com/PHP-Design-Patterns/Adapter/
Adapters are helpful if you want to use a class that doesn't have quite the exact methods you need, and you can't change the orignal class. The adapter can take the methods you can access in the original class, and adapt them into the methods you need.
I would say your code qualifies as an adapter if you plan to add methods to supplement another class.
I don't think you can pick one pattern and say that's the one being used here. Here's my little list of patterns I see in your example. Feel free to comment.
Delegation because the DBAdapter class delegates the task of getting the actual rows to the DB class.
Decorator because the DBAdapter class decorates the DB class with additional functionality - that of spitting the output in JSON.
Adapter/Wrapper if you think that it allows other client to access your database rows that only understood JSON or XML or some other format.
But if we had to pick one, I'd say Adapter. It takes the data in the form of PHP data structures and converts it into a JSON representation.
Related
I'm looking for some direction regarding the following, I'm new to OOP and getting there but think either my lack of understanding is causing me to get stuck in a rabbit hole or I'm just over thinking things too much and being anal.
basically i have a main class called "CurlRequest" which sole purpose is to perform curl requests, providing a url and params it returns me some html. This class works and functions as intended and I'm happy with that.
I use this class for a few projects but for one I then wanted to track the performance of my requests made. attempted, failed, passed etc, so i created a static class for this which manages all my counters. I place counter references like the following at different areas in my CurlRequest class.
PerformanceTracker::Increment('CurlRequest.Attempted');
PerformanceTracker::Increment('CurlRequest.Passed');
PerformanceTracker::Increment('CurlRequest.Failed');
I have around 10 or so of these with my class tracking all kinds of things during the curl request and i also use my PerformanceTracker class in other classes i made.
However like mentioned i only wanted to do this for one of my projects, so find my self in the situation of having my original CurlRequest class and an altered one with performance counters in it.
My question is, is their a way i can use the same class for any project and choose to use the PerformanceTracker class or not. The obvious way i thought of was to pass an $option argument into the class and then have if statements around all the counters, but can't help think its messy.
if ($this->options['perfCounter'] == true ) {
PerformanceTracker::Increment($this->owner . '.CurlRequest.Failed');
}
this also adds a lot of extra code to the class.
I suggest placing the if statement in a separate method
private function handlePerformanceTracker($q)
{
if ($this->options['perfCounter'] == true ) {
PerformanceTracker::Increment($q);
}
}
And call this method instead of your calls to
PerformanceTracker::Increment(...);
Also if you find that you want to track performance differently between your projects it might be useful to change your constructor to accept a callable argument, this way you externalize the actual implementation from the CurlRequest class itself.
public function __construct(..., callable performanceHandler)
Then when you instantiate your class:
$curlRequest = new CurlRequest(..., function($outcome) {
//your implementation
});
You can use inheritance and create a subclass that performs the logging before delegating to the parents methods:
class PerformanceTracker
{
static function Increment($s)
{
echo $s;
}
}
class CurlRequest
{
function get($url){
//preform curl request, save html to variable etc
//dummy vars used here so working example code
$html = 'html here';
$curlError = false;
if($curlError){
$this->error($curlError);
}
return $this->success($html);
}
protected function success($html)
{
return $html;
}
protected function error($curlError)
{
throw new Exception($curlError);
}
}
class LoggingCurlRequest extends CurlRequest
{
function get($url)
{
PerformanceTracker::Increment('CurlRequest.Attempted');
return parent::get($url);
}
function success($html)
{
PerformanceTracker::Increment('CurlRequest.Passed');
return parent::success($html);
}
function error($curlError)
{
PerformanceTracker::Increment('CurlRequest.Failed');
parent::error($curlError);
}
}
$lcr = new LoggingCurlRequest();
$lcr->get('unused in example');
As i have used dummy classes with minimal code to demo the technique the benefit might not be obvious, but in you real code, the methods in the CurlRequest class will be more complex, but the methods in the logging class will remain as two liners, with the log function and the call to the parent method.
Using this technique you can modify the parent class without effecting the derived classes (provided the method signatures dont change), can create other derived classes (how about a CachingCurlRequest) etc.
For the full benefits of OOP you should look into dependency injection and interfaces
From an OOP perspective you could use the 'Null' object pattern. This just means that the dependency used by the CurlRequest class is abstract (possibly an interface?). You would then have Two concrete implementations of PerformanceTracker: the one you have today and one that does nothing (it does not have any behavior). In this way for the one project when you instantiate the CurlRequest class it would use the concrete implementation that has behavior and for all the other projects it would use the concrete implementation with no behavior. All of the code in CurlRequest would look the same but it would have different behavior depending on which concrete implementation it was using
its gonna be a fully theoretical thread.
Let's talk about change arrays to specially object's, to compare and work on it.
For example we have a EntityClass, EntityInterface, SomeRepository, SomeManager, SomeCommand.
Entities is a clear object, example:
class EntityClass implements EntityInterface {
public $name;
public funtion getName() {
return $this->name;
}
public function assign($data) {
$this->name = $data['name'];
}
...
}
Repository ofc. have method's to save object in source and get it from source.
Manager have all of 'busines logic', it can modify a entities using command pattern, one command for one properties, so a busines logic for all properties its store in separate's command's, and manager fire it's.
Now, in manager start all logic and fun.
Little shorthand:
Repository create new entity by getOne().
We create a new instance of manager and pass by constructor some dependencies like array of data from controller and Entity.
Array of data have information about changes, example: ['name' => 'New name']; mapper resolve what command should have been fired by manager for given array.
Manager execute all commands for this request and passing raw array to each command.
Now, why we passing a array ? when we are in OOP, why don't use special variation of EntityClass ??
Now let's add a new interface EntityProposeInterface, and change a raw array to class implements this interface, and pass them.
for example we can add to SomeManager speciall method to morph entity like this (PHP7+):
class SomeManager {
public function morph($entity) {
$buff = new class extends EntityClass implements EntityProphoseInterface{};
$buff->assign($entity->toArray());
return $buff;
}
And now we have a EntityProphose lets make some changes on it, now manager change a EntityProphose from raw data array, and all commands and other method's in our code work's on object kinde EntityProphose instead of array.
But ofc. our repository cant save object's instance of EntityProphoseInterface.
And that's all...
Is there some design pattern name ? or something like this ?
Or this idea is very bad ?
I hope it's clear for all of you, if not please ask.
Any ideas ? advice ?
What makes me go crazy is why you would implement a function to assign values from an array to the whole class instead of just using regular assignments:
$entity->name = name;
$entity->age = age;
Perhaps you want to simplify this code... but what's the point of using arrays?
Your manager class (actually, a service) should provide functions with either parameters corresponding to whatever entity you want to modify or operate with, or just receive a DTO or the entity itself.
In the other hand, if you want to centralize how DTOs or entities are mapped one to another, maybe you need to implement object mappers:
class EntityMapper {
public function mapCustomerToCustomer($customerA, $customerB) {
if($customerA->name != null) {
$customerB->name = $customerA->name;
}
// and so on...
}
}
...and you can inject it wherever you want to map entities. For example, a CustomerService might look as follows:
class CustomerService {
function __construct($entityMapper) {
$this->entityMapper = $entityMapper;
}
public function update($customer) {
$customerToUpdate = $this->repository.getById($customer->id);
$this->entityMapper->mapCustomerToCustomer($customer, $customerToUpdate);
$this->repository.addOrUpdate($customerToUpdate);
}
}
I am having some trouble applying Factory Pattern.
I have a class that I usually call as Product($modelNumber, $wheelCount). But in a part of legacy code that I am refactoring, I do not have $modelNumber, and only have $productID, where the link between {$modelNumber, $productID} is in the database (or in my case I can hardcode it, as I only have a select few products at the moment).
I need to be able to create my class using $productId, but how?
Using Procedural ways I would have a function that does the lookup, and I would put that function in a file, and include that file anywhere where I need to do the lookup. Thus do this:
$modelNumber = modelLookup($productId)
Product($modelNumber, $wheelCount);
But how do I do it using Object Oriented way?
Note: I have posted a more detailed situation here: https://softwareengineering.stackexchange.com/q/233518/119333 and this is where Factory pattern (and other patterns, like interfaces and function pointer passing) were suggested conceptually, but I hit a wall when trying to implement them in PHP. It kind of seems like a simple question, but I think there are several ways to do it and I am a bit lost as to how. And so I need some help.
I provided a conceptual answer to your SRP problem on Programmers Exchange but I think I can demonstrate it here.
What you basically want is some other object that will do the work to get you the model number of given product ID.
class ProductModelNumberProvider {
public function findByProductId($productId) {
// The lookup logic...
}
}
Your factory should provide a setter constructor so it can make use of this object internally to lookup the model number if needed. So basically you will end up with a ProductFactory similar to this.
class ProductFactory {
private $productModelNumberProvider;
public function __construct(ProductModelNumberProvider $productModelNumberProvider) {
$this->productModelNumberProvider = $productModelNumberProvider;
}
public function getProductByIdAndWheels($productId, $wheels) {
$modelNumber = $this->productModelNumberProvider($productId);
return $this->getProductByModelNumberAndWheels($modelNumber, $wheels);
}
public function getProductByModelNumberAndWheels($modelNumber, $wheels) {
// Do your magic here...
return $product;
}
}
EDIT
On second thought the setter is not the best approach since having a ProductModelNumberProvider instance is mandatory. That is why I moved it to have it injected through the constructor instead.
I can think of something like this:
$factory = new ProductBuilder();
$factory->buildFromProductId($productId, $wheelCount); //uses modelLookup() internally
$factory->buildFromModelNumber($modelNumber, $wheelCount); //just returns Product()
It is basically creating a class on top of the procedural function, but it does separate the logic of creating the class separately from looking up the mapping.
Sometimes when I look at code other people have written I see something like the following:
<?php
namespace sys\database;
class Statistics {
public function __construct() {
// Database statistics are gathered here using
// private methods of the class and then set to
// class properties
}
public static function getInstance() {
return new \sys\database\Statistics();
}
// ...
}
So the static function getInstance() simply returns an object of the class it belongs to. Then, somewhere else in the code I come across this:
$stats = \sys\database\Statistics::getInstance();
Which simply sets $stats to an instance of the Statistics object, ready for its class properties to be accessed to get various database statistics.
I was wondering why it was done this way as opposed to just using $stats = new \sys\database\Statistics();. At the end of the day, all the logic to gather statistics is in the constructor and the getInstance() method doesn't do anything other than returning a new object.
Is there something I'm missing here?
This is supposed to be an implementation of the Singleton pattern: http://www.oodesign.com/singleton-pattern.html
The pattern is used to never allow more than one instance of the class to be created.
However, there are a couple of flaws with the implementation you provided: the constructor should be private, and there should be a single private static instance of the class, returned every time the getInstance method is called.
This is supposed to be an implementation of the Singleton pattern, which is a term used to describe a class which can only exist once for run-time.
It seems the implementation you have is flawed however because:
there is no check to see if the class exists yet and
code can create multiple instances by calling the constructor directly (it should be made private)
That's a [bad] implementation of the Singleton pattern.
As a rule of thumb, you should avoid such pattern in favour of more convenient Dependency Injection, for instance.
I am developing a PHP framework, based on dependency injection. My data objects are injectable components, like any others.
I have an abstract DAO class, that each model should extend, that has:
basic crud methods
a reference to DI container, to instantiate objects
Things are, in short, like this
abstract class AbstractDao {
protected $fields;
protected $container; // This is the (injected) DI container, used to create instances.
protected $driver; // The injected database driver (i.e. PDO)
public function insert() {
// Insert implementation
// Insert current instance.
}
public function fetch($id) {
// Fetch implementation
// Fetches a row and sets fields on current instance
}
public function fetchAll() {
// Performs a select * query on database driver
// Iterates through results, and creates an instance
// for each result using $container, like this:
foreach ($results as $row) {
// I can't just make $instances[] = new Something(), or all the
// dependency injection thing would mess up.
$instances[] = $this->container->get('someDao');
}
return $instances;
}
// Other methods.
}
class Book extends AbstractDao {
protected $fields = array('field', 'definition', 'goes', 'here',);
// No special behaviour is needed, so we can keep default
// abstract implementation without overriding.
}
My question: every data object implementation (a book, a person, an user, etc.) must extend my AbstractDao object, therefore it will carry the weight of $driver and $container. Furthermore, since $fields property is defined at instance level, each data object would have its own, adding more overhead.
I fear that when handling big data sets this solution may result in a much expensive one, in terms of performance. I know objects would be just referenced, not cloned, but the overhead could be sadly high.
Couple of solutions i have in mind are
using static method implementations, that may reduce overhead in
subclasses
do not make my Daos extends the above mentioned AbstractDao, that should become a sort of DaoProvider. In this case, for each method, i should pass in the instance (thing that i don't really like)
None of those solutions i like that much... first i don't like using static things, as they conflicts a little with the entire idea of injection. Second, i dont like the idea of removing the dao subclassing pattern.
Any good idea would be really appreciated, thank you.
=== EDIT ===
One more thing that came to my mind. What i don't like in the 2nd approach ("dao provider") is that the provider has to perform operations on Dao fields (set values, set status, set isDirty, etc.), therefore fields have to be made accessible from outside. With the subclassing approach one can keep those protected or private.
=== /EDIT ===
I suggest you create a DAO Interface that declares behavior that a DAO implementation will have to define. Now in each concrete DAO implementation you can define your $driver, $container and $fieldsinstance fields.
After that you might want to create a AbstractModelclass that each concrete model should extend so that both your AbstractModeland concrete models be will 'data access agnostic'. The AbstractModel class will end up looking like this:
/*
* an AbstractModel
*/
abstract class AbstractModel {
protected $daoImpl;
function __construct(DAOInterface $daoImpl) {
$this->daoImpl = $daoImpl;
}
//some other functions that are common to concrete models
}
/*
* a concrete model
*/
class Model extends AbstractModel {
function findAll($params) {
//You can use the $daoImpl of AbstractModel to perform a CRUD operation
$this->daoImpl->findAll($params);
}
}
Now whenever you instantiate a concrete model you will inject a DAO implementation into the model class.
//inject a DAOInterface implementation into Model
$model = new Model(new DAOImpl());
$model->findAll($params);
The advantage here is that you can stub different DAO implementations during testing and perhaps this is where the DI container comes in handy. There's a similar code sample I have created when I was creating my DI container a few days ago.
BTW I don't see the need of putting a $containerobject inside your AbstractDAO why don't you pass in an object that is returned when you invoke a property of the container. That way you can use type hinting to force the object parameters to be of a certain type and encourage a fail-fast mechanism if a wrong object is passed in and you might also find it beneficial to create a Config class to handle your $driver details so that users are free to configure the driver they want to use for the db.