Dangling Cruze Dangling Cruze - 7 months ago 16
PHP Question

SOLID principles while creating objects

Here's the scenario:


A User can create shapes using a form.

User will select from a list of options of shapes (circle, square, rectangle and so on) and submit the form by clicking on create shape button.

The shape he created will be linked to his account.


Here's how I'm approaching it:

An Interface
Shape
with a method signature to
create()
a shape, which will be implemented by individual shape classes.

# Shape.php
interface Shape {
public function create();
public function area();
}

# Rectangle.php
class Rectangle implements Shape {
private $user;
private $data; # user submitted data

public __construct($user, $data) {
$this->user = $user;
$this->data = $data;
}

public function create() {

# get rectangle shape details from RectangleShapeAPI

$userShape = new UserShape; # the model to store data
$userShape->shape_id = $this->data['shape_id'];
$userShape->area = $this->area();
$userShape->users_id = $user->id;

# save rectangle shape details from API

if (!$userShape->save()) {
return false;
}
return true;
}

public function area() {
return $this->data['length'] * $this->data['breadth'];
}
}


Now, I've to
switch($shapeType)
over the shape type selected by the user to instantiate the
Square
or
Circle
or
Rectangle
classes appropriately.

$data = $_POST;
switch($shapeType) {
case 'square':
Shape $shape = new Square($user, $data);
$shape->create();
break;

and so on...

}



This is my first step towards implementing
SOLID Principles
and I
think I may have gotten it wrong. Please forgive me in that case.

The problem is I think the switch statement (I've seen examples
where people try to eliminate
switch
or
conditions
when they try
to use those objects). I've seen this only at the time of using the
objects which I think is possible very easily. But can we achieve the
same during the time of object creation (I am not able to find any
logical solution to this other than
switch
ing over shapes).

Other thing is, how to handle the
$_POST
data effectively as the
keys to the array may change in future and anything may happen. How
would you handle this scenario?





The above explanation is the simplified version of my case.

I have an
Accounts
Interface with
add()
method that is implemented by
FacebookAccount
,
GoogleAccount
and other classes.

Now the methods to
add()
these accounts are different, hence used as an interface. The
Facebook
or
Google
api objects are created and user data is fetched to store into
UserAccount
. The accounts are linked to the user.




I welcome all those who wants to give me their way towards approaching this problem using SOLID Principles. I will be very thankful to all and hope I will learn a lot of things about the principles and what I'm doing wrong.

Thank you.




EDIT

Link to SOLID Principles: SOLID Principles Wikipedia

Answer

Finally came up with solutions to both problems.

The switch problem

Create a factory class that will return the required object. This will hide the conditional complexity of retrieving an object from the scene.

The $_POST data problem

This was actually quite easy and is common sense to pass the data to the create method instead of passing to the constructor. Passing the data to the create method solves this issue as the method only deals with creating new object and the other parts of class are now independent of that change.