Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

OO or just OOps ?

by guha (Priest)
on Sep 23, 2002 at 13:18 UTC ( [id://200085]=perlquestion: print w/replies, xml ) Need Help??

guha has asked for the wisdom of the Perl Monks concerning the following question:

Background:

Recently I bought myself "Object Oriented Perl" by the esteemed Damian Conway. Interesting reading I thought, but I know the old saying that reading isn't knowing.

So I thought the the next project would be OO, getting my feet wet and all that.

The Project:

The project is what you might call an order confirmer, that gets information from SQL-databases, generates nice output in MS Word and automatically sends the confirmation to client as either Fax or PDF.

The Problem:

I have done similar, in some sense, imperative program where the data has been organized as a treelike structure in a hash, and where I have showed a reference to this hash around to the various subroutines. This has worked well the main feature being short argument lists, but I imagined that OO would be safer and prettier.

In the non-OO solution I would have something like this

Most of the toplevel keys of the hash maps *almost* to tables in the database, however the real app is much more complicated than the example below suggests, so relying more on the database is not an option.

%obj = ( CFG => { DSN => 'test', PDF => 'MyPDFdriver', }, CLIENT => { 10101 => { Name => 'Client Name1', Adress => 'Adress1', Phone => '555-7865', Media => 'Mail', }, 10102 => { Name => 'Client Name2', Adress => 'Adress2', Phone => '555-7866' Media => 'Fax', }, }, ORDER => { 2ZXWEQ => { CLIENT => 10101, Info => 'Pix proj 123', ITEMS => [VX12345, VX12346], }, 3ZSIUY => { CLIENT => 10101, Info => 'Something else', ITEMS => [VX12347, VX12348], }, }, ITEM => { VX12345 => { ORDER => 2ZXWEQ, TYPE => HW33, Price => 123, }, VX12346 => { ORDER => 2ZXWEQ, TYPE => HW33, Price => 123, }, VX12347 => { ORDER => 3ZSIUY, TYPE => HW34, Price => 155, }, VX12348 => { ORDER => 3ZSIUY, TYPE => SW12, Price => 1203, }, }, TYPE => { HW33 => 'foo manipulator', HW34 => 'bar stimulator', SW12 => 'baz simulator', }, ); so print $obj->{TYPE}{ $obj->{ITEM}{VX12348}{TYPE} } would yield baz stimulator

So I figured that making a class of each of the top level hash keys and somehow make it act as a container for instances of that class.

However my limited OO knowledge can't seem to grasp how to get or set the different attributes of a parallell branch in the tree structure for instance.

Should I have organized the data differently ?

Is it altogether a bad case for OO ?

Does anyone have any ideas ?

TIA

Replies are listed 'Best First'.
•Re: OO or just OOps ?
by merlyn (Sage) on Sep 23, 2002 at 14:14 UTC
    "data" is never really a good candidate for being "an object". What is the role this data plays in your program?

    The point of OO is to take the "objects" of your problem, and represent them in your program as "Objects" with behavior and state, and to also capture similarities of object behavior in an inheritance hierarchy for code reuse.

    So, no, one nested hash does not a candidate for Objects make. {grin}

    -- Randal L. Schwartz, Perl hacker

      Well,
      I thought I wanted Client to be an class, with accessors for the attributes and then have several instances of them, one for each client.

      The same for orders and items

      Perhaps a class for konfiguration data instead of globals floating around

      And then to avoid redundancy the TYPE could be "class"-ifyed

      I known my post is muddy at best, but what I was trying to avoid is that the communication between objects would nessitate having to juggle several objects of different classes to perform the action.

      As an example consider selecting what media a certain client wants his confirmation, which would be found in the client instance and pertinent data would also be found in the configuration instance.

      And yeah I know, messed up design, but that was really the reason for my question

      I am sorry but I don't understand the first statement. I know I am (much) less experienced then you but I thought people often encapsulate data in objects and use accessor methods to get at the data. The accessor methods provide verifcation of data structure over and above what the use of datatypes can provide.

      With all due respect,

      --blm--
        That would be "procedural programming with objects".

        You can find much better approaches out there. (Yeah, it is in Java. Take good advice where you find it.)

Re: OO or just OOps ?
by BUU (Prior) on Sep 23, 2002 at 13:29 UTC
    The main advantage of OO is that it 'hides' your data persistence. So instead of having to constantly call foo($baz,'data1'); qux($baz,'data2'); you could do $baz->foo('data1'); $baz->qux('data2'); As such, its purely semantic, and has (to my knowledge) very little relationship with datastructures, unless you contemplate replacing just a basic hash/access structure with real accessors, such as $hash->{key} vs $obj->get('key');. which would allow you to hide exactly how you return the value of the key. (of course, you could tie the hash, but thats evil...)
Re: OO or just OOps ?
by Ryszard (Priest) on Sep 23, 2002 at 15:37 UTC
    How about your object doing something like returning your data structure ala:
    my $obj = Orderconfirmer->new; $obj->fetchdata(type => all); $obj->fetchdata(name => 'foo'); $obj->createinvoice(type => 'msword', name => 'foo);

    What youre doing is creating an interface for anothoer prgy to use. The advantage is that you have "abstraction". You create all the business logic in one script, encapsulate your data fetching/processing in another script, so when your backend changes, you re-write your OO module (being careful to preserve the interface you've defined) and dont have to touch your business logic.

    Of course in the above example you can abstract further, having one module fetch all the data from a database, and the other module build your word/pdf/whatever invoices.

    So an object has methods, the methods do *something*, they can do whatever you program them to do. An object also has attributes, these attributes are things like "name". A method can use an attribute to to its processing, using the above example, the fetchdata method uses the attribute of name to define what to search for...

      You write about a single class Orderconfirmer which all methods belong to.

      Using a singleton gains little compared to

      my %obj; fetchdata(\%obj, type => all); fetchdata(\%obj, name => 'foo'); createinvoice(\%obj, type => 'msword', name => 'foo);
      IMVHO (v stands for very)

      It is in fact how my abovementioned non-OO version was designed.

      What I wanted was to put different things in different classes, having their own methods and accessors.

      I guess 5-6 classes would seem resonably for this application, some classes would have just one instance and others like ORDER and ITEM would have plenty of instances, created and populated during data fetch. These instances would have to be accessed during the invoice building so there needs to be a way to access instances of other classes there.

      And that was my real question from the beginning, even though I failed to communicate that.

      The real problem is that I don't have any OO background, apart from Damians book, Perl toot and Perl boot, (thanks merlyn)

      Anyway thanks for your input, things seem to demuddle as I try to explain myself.

        Why are you going about this backwards?

        You can't figure out how to do an OO design. But you already know what you want to have in classes, how many classes you need, and so on. Where are you pulling these things from? Thin air?

        Lesson 1. OO programming works differently than procedural does. It is a different way of decomposing your problem space. Think of a machine. Procedural programming is like describing the sequence of actions that take place in a machine resulting in the action. OO programming is like describing what a screw is. Building on that to describe a hinge. And so on until you have a description of a machine that does useful stuff.

        So what components would be useful for you? What kinds of things would they do? Don't jump to how they might do them! Just focus on the components and their interfaces. Each type of component is a class, and the interface is its methods. The methods need not include accessors. Would you ask a door how it is made? Then why would you expect an object in an OO system to need to do so?

Re: OO or just OOps ? (Joke/OFFTOPIC)
by Flexx (Pilgrim) on Sep 23, 2002 at 15:32 UTC

    I'd like to order such a "bar stimulator", please.. >;)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://200085]
Approved by valdez
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-23 11:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found