Search code examples
phpoopsolid-principles

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 switching 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


Solution

  • 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.