0

I am refactoring legacy codebase. Part of it is a loadProduct() function inside a larger "everything" class. loadProduct() loads data from a database. I want to move this loading-data part out of the larger class, because I do not think it belongs there. I am not sure exactly where I want to move it yet, but I think that just moving it out into a separate class will do great to start.

How do I do this?

i.e. Imagine this:

class Big
{
    function x() {}
    function y() {}
    function z() {}
    function w() {}

    ...

    function loadProduct()
    {
        $sql = "select * from X where Y = $this->p1 and w = $this->p2";
        $result = db_call($sql);
        ...
        $this->a = $result->field_a; 
    }
}

What I think of so far is:

  1. I can create a Product class that instantiates and returns the product data. Call it i.e. $data = new Product($p1, $p2, $p3).

  2. create a ProductProvider class, which has function loadFromDB(). Call it:

$pp = new ProductProvider();
$data = $pp->loadFromDB($p1, $p2, $p3);
...
include 'db.php';
class ProductProvider()
{
    function loadFromDB($p1, $p2, $p3)
    {
         $product = null;
         //code to load Product
         return $product;
    }
}

I think way 2 is a bit more flexible and allows me to add more functions later on, such as loading different sets of data from different sets of parameters. This flexibility may come in useful in case legacy codebase gives me surprises later on. (i.e. say as I refactor I may realize I need to move or group this data-loading piece into or with some other piece of code and code encapsulation Provider will give me should be easy to move elsewhere).

Will my 2nd example pattern be a proper* fit for my refactoring example?

  • By proper fit I mean industry-accepted best practice, recommended for cases similar to mine.
  • When you say "good fit," what do you mean by that specifically (other than being popular or generally-accepted)? Is this the provider pattern you are referring to? Because it seems to me like it is merely a specific implementation of Factory Methods. – Robert Harvey Mar 31 '14 at 17:06
  • Usually an entity should not know how to load itself from the database. You also forgot to pass the database to your constructor/provider. – CodesInChaos Mar 31 '14 at 17:13
  • my question is basically, when you have a large everything class, how do you pull out a certain function out of it for the purpose of refactoring. Database is currently global, but later it may be directly loaded in the class itself. – Dennis Mar 31 '14 at 19:50
  • 1
    The way you refactor a single function out of a class is to provide all of the required dependencies to the function, and then return the value you need. – Robert Harvey Mar 31 '14 at 21:12
1

As asked in the title, you are probably looking for the Data Access Object pattern, that is also discussed in this StackOverflow question.

The point is using software layers to separate the program logic from database structure, because this way you could change your database schema, the names of the tables, and modify a small and isolated part of your code. Also having all DAO classes in the same package would help if the Database Management System changes. An example of possible change is moving from relational to NoSQL.

As pointed in the comments and explained by Mak Seeman, Provider is not a pattern. All code that is called at least once, provides some service. The name of a class should reflect what is provided, and not the fact that it provides something.

  • it looks like the construct I called "Provider" in my question is pretty much like DAO - i.e. functions used to load data from the database, encapsulated into a class. DAO though does not seem to get negative/confusing connotation as the "Provider" construct. And DAO has clearer/more established purpose (provides a separating layer) and conventions, such as findById(). Thanks. – Dennis Mar 31 '14 at 22:09
  • I do not see much shame in calling this a "provider". This DAO will provide data from the database for me. – Dennis Mar 31 '14 at 22:34
  • @Dennis I have updated my answer. – Виталий Олегович Apr 1 '14 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.