SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member jcesar's Avatar
    Join Date
    Sep 2003
    Location
    Colombia
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question Database access encapsulation

    Hi,

    I've been following the thread on "OOP method" bellow, and have some doubts about the extendability of the design. So far, the class allows add, edit, delete and findByPoster.

    For small tables those four methods are all we need, but for a comments table there's probably lots of other queries that shall be needed.

    For example, "get yesterday comments", "list all comments by some poster" or simply "list page n, 10 comments at a time". All of those are easy to implement using SQL (and a faster implementation than reading one comment at time) but I would like to encapsulate database access as much as posible.

    So, what to do in this case? Create a lot of classes? (like "ListLastWeekComments", "CommentsPagedList", etc). Something like:

    Code:
    interface ICommentManager
    {
    	bool load([] &$comment);
    	bool loadByPoster([] &$comment);
    	bool insert([] &$comment);
    	bool update([] &$comment);
    	bool delete([] $comment);
    }
    
    interface IListLatestComments
    {
    	void setMaxRecords(int);
    	bool fill([][] $dataSet);
    }
    
    
    interface ICommentsPagedList
    {
    	void setMaxRecords(int);
    	void setCurrentPage(int);
    	bool fill([][] $dataSet);
    }
    Surely, I don't want to start creating a method for each of those statements. This is a case for the Open/Close principle, right?

    Thanks,
    Julio CÚsar Carrascal

  2. #2
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Create a method for each stated case ? Umm... Yes, and why not aye ? What you are thinking is DAOs and that is perfectly valid.

    Your DAO would have a method for every SQL query that you may have and you return the resultset back to the class that instaniated the DAO in the first place yes ?

    You may be thinking in your case that you have logic in the class for each method as well though I wouldn't recommend that.

    Look at past threads here at Site Point and take a look over at www.phppatterns.com as well ?

  3. #3
    ********* Victim lastcraft's Avatar
    Join Date
    Apr 2003
    Location
    London
    Posts
    2,423
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Hi.

    Regarding the OOP method thread, I very much had to go one step at a time. I wouldn't regard the current state as anything like finished. I think the pattern is ActiveRecord in Fowler terms (if memory serves) and is a nice step up because once you do a couple of them you start to see commonality and can start to build more generic versions.

    As for your version, you have the big three. The object that wraps the database data, a broker to fetch it and a collection for the bulk results.

    The core of your query is how to do the broker, yes? The problem at the moment is that every time you add a new type of object you have to extend two new classes, a specialist broker and specialist data object. There are at least two divergent solutions I can think of...

    First make the broker generic. One way to do this is to have the the broker construct the SQL from simpler parts and fill the blanks...
    PHP Code:
    $broker = &new PersistenceBroker('Comment');
    $broker->addCondition('age > 5');
    $result = &$broker->find();
    while (
    $comment = &$result->next()) {
        ....

    The $comment variable is an instance of the Comment class. The PersistenceBroker and Comment have to read some kind of table and column mapping to do the translations. The Comment class can write itself back out using the broker as well and create other brokers to load sub-parts. In this case you can also add your own specialist functionailty to the Comment class. It then becomes a full domain object. The downside is that it treats the database as just a data store, but if your requirement change constantly that is probably what you want.

    This is basically a factory pattern.

    The other approach is to have lots of brokers...
    PHP Code:
    $broker = &new CommentBroker();
    $result = &$broker->findOld();
    while (
    $comment = &$result->next()) {
        ....

    I haven't tried this out. The resulting objects are dummer and so they rely on call backs to the broker that created them. If you want a domain object then you have to decorate the resulting data object which are now more generic. You data is a bit dummer, but I can imagine this being easier to manage, especially if there are lots of block operations or the select queries are specialised (say stored procedures). This is more of a two tier approach.

    This is basically a builder pattern.

    yours, Marcus
    Marcus Baker
    Testing: SimpleTest, Cgreen, Fakemail
    Other: Phemto dependency injector
    Books: PHP in Action, 97 things

  4. #4
    SitePoint Member jcesar's Avatar
    Join Date
    Sep 2003
    Location
    Colombia
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Create a method for each stated case ? Umm... Yes, and why not aye ? What you are thinking is DAOs and that is perfectly valid.
    Well, the thing is that I wan't classes to be as closed as posible. What I mean is that if one month from now, my client want something new that I can do with a simple SQL query I don't have to modify that class. Maybe add another that can do the work.

    That's what I have been doing until now but I wanted to know what do you people think about this method.

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm.... You create a new class to query a database ?

    May work I suppose short term but over a period of time your going to have a lot of classes aren't you ?

    Unless you delete the old classes as you go along ?

    To me though this seams a bit extreme to create a new class for every new database query ? Say you have a series of classes using one database and later you need to change databases ?

    Anyway, regardless of how you use a database or for what purpose I still believe that DAOs are the solution to allowing you to expand your data retreival/storage.

    Okay, you may need to change a class for example which has a given amount of methods to query the database for example, news or logs.

    But it's only one class to re-create for example, for changing databases ?

    Have you looked at HarryF's site for an example of using DAOs ? That'd give a more clearer example of what DAOs can and are used for IMO...

  6. #6
    SitePoint Member jcesar's Avatar
    Join Date
    Sep 2003
    Location
    Colombia
    Posts
    21
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Dr Livingston
    Umm.... You create a new class to query a database ?

    May work I suppose short term but over a period of time your going to have a lot of classes aren't you ?
    A lot of (small and easy to edit) classes, yes. The thing is that I use ADOdb for database independence and that I can do a lot of optimizations to the SQL.

    For example I do a Prepare() in the constructor so MSSQL and Oracle parse the query there and then I can call the method as many times as I wan't obtaining better performance.

    [code="php"]
    $query = &new SomeQueryList(); // Prepare()
    $query->fill($dataSet);

    foreach ($records as $record) {
    $query = &new DeleteSomeRecord();
    $query->execute($record)
    }
    [/code]


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •