SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Enthusiast rikdc's Avatar
    Join Date
    Sep 2005
    Location
    Edinburgh
    Posts
    71
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    "Printer" abstraction

    Hullo!

    What I'm trying to do is wrap up displaying a persons address. In some cases I might want a single line view, in others I might want it multiline. And in others, I might even wawnt it in a <textarea>, thus the multiline needs \n and not <br />.

    I originally looked at an Address class and had a "factory" function which returned the appropriate format, but I read in here that this is potentially a smell.

    So, I took it to another level, creating an AddressPrinter class. AddressPrinter, AddresssSingleLinePrinter, AddressMultiLinePrinter etc etc. Each class has a getAddressString(), which returns the formatted text.

    At code level, Address->print( new Address????Printer() );

    Can anyone pass comment; from an OO development perspective am I hitting on good practise, or have I missed the point of decoupling responsibility?

  2. #2
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That seems like a lot of different classes for what ultimately is a pretty simple task: formatting a piece of data for displaying on the page.

    Have you considered using a template engine? Maybe having different templates for each way you want to display an address (ie: tpl.address_single_line.php, tpl.address_multi_line.php, tpl.address_textarea.php)
    Garcia

  3. #3
    SitePoint Enthusiast rikdc's Avatar
    Join Date
    Sep 2005
    Location
    Edinburgh
    Posts
    71
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hmm, this is true, though depending on the template engine, my 7 line class is comparatively more simple and uses far less code than say, Smarty. On the other side of the coin, it could be argued that my multiple-class approach is also a form of template engine.

    My question was really aimed at keeping my objects decoupled, using appropriate(?) pattern/methods. I had a class to represent a users address - quite the cliché starting point! - and in different areas of the system the address was being echo'd to screen, but in different formats. Rather than having toAddressMultilineString(), toAddressXml(), toAddressSingleLineString(), toAddressMorseCode() etc as a function, I [decorate?] the address class with a new printer, removing the responsibility of knowing n different formatting rules from the Address class.

  4. #4
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, you wouldn't really use a template engine just to display an address. If you had one, you would use it all throughout your application, so there would be no additional overhead to use it for addresses as well.

    But it sounds like your design doesn't really use a template engine. In that case, I believe that you are taking the right approach, in that I suppose that there are some common methods to all addresses, so your base class can remain the same. Splitting up the formatting of the address by class, seems like a good idea to me.
    Garcia

  5. #5
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Have you considered using Visitors?

    http://www.dofactory.com/Patterns/PatternVisitor.aspx for a better idea of what I mean. This is how I manage to transform an XML fragment (one of many, in which case, most fragments are originally xHTML) to xHTML in a singular case.

    The Visitors are clearly decoupled from the Controllers, so these can accept one of many Visitors, ie In your case, Printers. Decorators might work, but in that regards, you are creating more maintenance for yourself down the road.

    Have a look at the Visitor pattern anyways, and see what you think. I might be able to shed some light on the matter if you run into some trouble

  6. #6
    SitePoint Addict
    Join Date
    Apr 2002
    Posts
    330
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by rikdc
    What I'm trying to do is wrap up displaying a persons address. In some cases I might want a single line view, in others I might want it multiline. And in others, I might even wawnt it in a <textarea>, thus the multiline needs \n and not <br />.

    I originally looked at an Address class and had a "factory" function which returned the appropriate format, but I read in here that this is potentially a smell.

    So, I took it to another level, creating an AddressPrinter class. AddressPrinter, AddresssSingleLinePrinter, AddressMultiLinePrinter etc etc. Each class has a getAddressString(), which returns the formatted text.

    At code level, Address->print( new Address????Printer() );

    Can anyone pass comment; from an OO development perspective am I hitting on good practise, or have I missed the point of decoupling responsibility?
    I am not sure if you mean printer as in printing in paper, but you may want to take a look at this Printer Abstraction class that was just released.

    <advisor edit>Removed self promotional link</advisor edit>
    Last edited by Helge; Feb 16, 2006 at 08:54.
    Manuel Lemos

    Metastorage - Data object relational mapping layer generator
    PHP Classes - Free ready to use OOP components in PHP

  7. #7
    SitePoint Enthusiast rikdc's Avatar
    Join Date
    Sep 2005
    Location
    Edinburgh
    Posts
    71
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry about a slow response, ghurtado, Dr Livingston, and mlemos - thanks for your replies!

    mlemos - I didn't mean a "real" printer, but that printer class is certainly worth bookmarking

    ghurtado - It's good to get some confirmation that I'm not completely barmey with my imlementation ideas!

    Dr Livingston - the visitor pattern does look pretty handy, though I can't quite see how it'll save the number of classes for the different display formats of an address?

    I'm working with Mojavi, and inside the "Views", I am setting a range of variables to the "Renderer". Personally, I think that I am probably using the Mojavi render incorrectly, but I've used the "Mojavi" template files to define a region, for example:

    <!-- Header -->
    <h1><?php echo $tempate[ 'title' ]; ?>

    <-- Start Grid -->
    <?php echo $template[ 'customer_grid' ]; ?>


    and the cosmetic HTML to define inputs.


    Inside the Mojavi's "View" class, I do something along the lines of:

    $ap = new CustomerPrinter( $customers ); // where Customers is an array of "Customer" classes.

    $render->setAttribute( 'customer_grid' , $ap->fetchBuffer() );


    If you could comment on this approach, I would appreciate it.

  8. #8
    SitePoint Wizard
    Join Date
    Aug 2004
    Location
    California
    Posts
    1,672
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by rikdc
    Inside the Mojavi's "View" class, I do something along the lines of:

    $ap = new CustomerPrinter( $customers ); // where Customers is an array of "Customer" classes.

    $render->setAttribute( 'customer_grid' , $ap->fetchBuffer() );


    If you could comment on this approach, I would appreciate it.
    That looks like TemplateView to me in a sort of backward way. Why not just use a Template class?
    Christopher

  9. #9
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by arborint
    That looks like TemplateView to me in a sort of backward way. Why not just use a Template class?
    That would probably be the more sensible approach. You could then define your "printers" as filters that are used by the template class. Something like:
    PHP Code:
    <!-- Start Grid -->
    <table>
    <?php foreach ($template['customers'] as $oneCustomer?>
    <tr>
        <td>
    <?php echo $template->filter($oneCustomer['customer_address'], 'customerAddressTablePrinter'); ?>
       </td>
    </tr>
    <?php // end foreach ?>
    </table>
    <!-- end grid -->
    Garcia

  10. #10
    SitePoint Enthusiast rikdc's Avatar
    Join Date
    Sep 2005
    Location
    Edinburgh
    Posts
    71
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Why? Never really considered it!

    Reading up through my PoEAA now, using a helper class. It all seems to make good sense, I'm just trying to put it into application.

    ghuarto.. Do you pass a classname to the "filter" function so to keep the code inside the template simple?

  11. #11
    SitePoint Evangelist ghurtado's Avatar
    Join Date
    Sep 2003
    Location
    Wixom, Michigan
    Posts
    591
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes, the main idea is that you strip as much logic as possible from your templates, so as to provide greater reusability.

    The template class I currently use is a really simple PHP based template engine (as many other PHP developers do, I assume), something I hacked together in a couple of days. As such, all of my templates are PHP files, although I try to keep the PHP within the templates to a minimum (conditionals, loops, a little formatting and little else).
    Garcia


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
  •