简体   繁体   中英

php - how to improve code with OOP

This is maybe discussed several times but I want to know how OOP can help me improve my code. I used to code in procedural way. However with a reasonable logic. The pieces of code that are used all over the project are wrapped in functions. however all functions are put in a large functions.php file (which I find not very efficient). for example, this is a function to check if a sales is expired or not :

function is_sales_expired($salesId, PDO $conn) {
    $now=time();
    $sql="SELECT * FROM specialoffers WHERE id=:id";
    $st=$conn->prepare($sql);
    $st->bindvalue(":id",$salesId,PDO::PARAM_STR);
    $st->execute();
    $sales_array=$st->fetchAll();
    if($now<$sales_array[0]['finishdate'] && $now>$sales_array[0]['startdate']) {
        return FALSE;
    } else {
        return TRUE;
    }
}

Now Ive decided to move to OOP and convert my code to OOP. So I created classes and put the functions related to a particular behavior into each class. for example a sales class which has a is_sales_expired() and other methods related to sales. the properties and the constructor look like this :

class Sales
{
    private $conn;
    private $stockObj;
    private $userObj;
    private $cartObj;
    private $randomObj;

    function __construct(PDO $conn)
    {
        $this->conn = $conn;
        $this->stockObj = new Stock($this->conn);
        $this->userObj = new User($this->conn);
        $this->cartObj = new Cart($this->conn);
        $this->randomObj = new Random($this->conn);
    }
    //methods come here//
}

And then I load the classes in my code using spl_autoload_register so I don't have to include all class files in every other file. Well with this approach, calling methods is a bit easier and I don't need to pass PDO $conn to every method call and it is already passed with the constructor.

Well, these are all good and all related codes are now in one place and maybe a bit easier to manage. But I have a feeling that the OOP should have much more to offer. with the Approach that I used, I don't feel, that now my code is more efficient and maintainable. I feel I should have missed some concepts here. your help is appreciated.

It is good that you have started organizing your code into objects, this is a good move into the better application structure. Once when you start looking deeper into it, you will find ways to split your current objects into even smaller parts and organize them in better ways, having less code solving more problems in more flexible ways.

For example, in your code the business logic is still tightly coupled to the database. What if you decide to use mysqli instead of PDO ? You'll have to touch every class in your application.

But if the database interaction was extracted into own set of objects that were used by your business logic, it would be much easier to replace the database access layer. In fact, you could quite easily replace MySQL with PostgreSQL or even with plain files in that case.

I can think of two ways to learn more about how OOP works: read a book or learn from the existing code.

The book I linked is my favorite OOP book and shows some very good examples of how the problem can be solved with OOP by decomposing the program into the co-operating objects.

And I'd also recommend starting using some OOP framework, I had some good experience with Yii in the past, check the guide to see how it looks like. You'll see tons of useful objects solving various problems you have to solve all the time when developing a web application. Try to build some simple application with it and then try to look inside the framework code to see how it actually works.

One more advice is to look into automatic testing. This will not only keep your application alive, but will teach you how to compose better objects. You'll have to use your classes in two different situations - your actual code and tests. Inside tests you will want to isolate the object you are testing from the rest of the code, for example, test the sales stats algorithms without touching the database. And you'll have to split you code into smaller and more flexible structure to be able to do that.

You are off to a good start and it takes time to start thinking of an architecture of objects. The strength of OOP is that it can mimic the things in which your code must interact. So think of things that it needs to handle and actions it will need to do. So in your example, you could have a new class SpecialOffers, which will handle all things related to your specialoffers table.

For example:

class SpecialOffers {

function __construct(PDO $conn)
{
    // this is connected to the server table
    $this->conn = $conn;

}

// get the details of a special offer
private function get($salesId) {

    $sql="SELECT * FROM specialoffers WHERE id=:id LIMIT 1";
    $st=$this->conn->prepare($sql);
    $st->bindvalue(":id",$salesId,PDO::PARAM_STR);
    $st->execute();
    $rows = $st->fetchAll();

    if (count($rows) > 0) {
        return $rows[0];
    } else {
        return null;
    }

}

// answers whether a particular sales is active
public function isActive($salesId) {
    $answer = $this->get($salesId);

    if (isset($answer['finishdate']) && isset($answer['startdate'])) {
        $now=time();
        return $now<$answer['finishdate'] && $now>$answer['startdate'];          
    } else {
        return false;
    }

}

}

There are still many more things to do, like error processing, but you can see how it starts to become more obvious as things get broken down, and you are thinking only about special offers. How do they work? What can go wrong?

Lastly, the best piece of advice when trying to think of the scope of a class is from the SOLID principle. The first one, S - Single Responsibility Principle:

a class should have only a single responsibility (ie only one potential change in the software's specification should be able to affect the specification of the class)

The best class can be described by one sentence. Same as well for methods, one sentence to describe what it does.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM