Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: The division of (class) labor in OOP

by tilly (Archbishop)
on Jun 06, 2005 at 04:56 UTC ( [id://463831]=note: print w/replies, xml ) Need Help??


in reply to The division of (class) labor in OOP

If you're getting confused about the design of your classes, here's a simple rule of thumb that often is appropriate.

Make your classes be nouns, and your methods verbs.

That is, classes are things in your design. Methods are what those things do. This isn't, of course, the only way to design an OO system. But it is a principle that generally leads to reasonable designs, and can sort out a lot of confusion about where the boundaries of class responsibility lie.

With this principle in mind, User is a reasonable class. It represents a person. But Authentication is not a good class. It sounds too much like a verb. If you don't want to put authentication methods into User, the suggestion above to have a Session class makes a lot of sense. In that design responsibility for authentication gets shared. It is up to the Session to know who is logged in. But when you try to login, the Session will have to ask the User to verify the password.

Let's apply this principle to the second problem. Display again sounds like an action, and therefore is a bad candidate for a class. For one thing you're going to have confusion about where methods go. (If I want to display information about a user, where does Display leave off and User begin?) How should you replace it? One approach is to say that Users know how to display themselves. But this turns out to be a bad factoring as you get many different ways in which user information is displayed - User is supposed to know about being a User, not about HTML, reporting, and so on.

A popular solution is the Model-View-Controller paradigm. In this paradigm User is a Model class, it represents actual information about someone in your system. Your Views are your actual output code, generally these are not classes but are actual web pages. The Controller is where Model meets View. It specifies business rules about how and why the Model will change.

In that paradigm, the answer to your question is as follows. You have code that displays and accepts the login attempt. That code calls the appropriate Controller to find out what View comes next. That Controller checks with the Model (in this case User and/or Session) to find out whether a login attempt succeeded, and then decides whether you're next going to have a login failure view (and if so then which one), or an account page.

This may sound complex, but it isn't really. In practice you'll find that your views are very straightforward. Your Models are also straightforward. The icky logic winds up in the Controller. While it still gets icky as business rules pile up, you at least know where to look for that logic in your system.

If you're interested, CGI::Application and CGI::Prototype are two modules to help you get going on writing MVC applications in Perl. Maypole and Catalyst bill themselves as frameworks to help you do the same, the former is simpler but will restrict you more if you want to vary from The Chosen Path. The latter is more complex and flexible. I know that you'll be able to get help at Perlmonks for the two modules that I named. I'm less sure that you'll get good help (though you may) for the frameworks.

  • Comment on Re: The division of (class) labor in OOP

Replies are listed 'Best First'.
Re^2: The division of (class) labor in OOP
by hakkr (Chaplain) on Jun 06, 2005 at 09:40 UTC

    You should take a look at OO design patterns in general MVC is one of the main ones related to creating tiers/layers within your application. You'll find these problems/decisons are repeated in every project. If you are working in a team there can be big benefits in code standards by using a framework.

    Tilly's advice is good, the priciple is to constantly ask yourself if you have chosen the correct objects(things).

    Lookup 'software cohesion' also, the more you have discrete objects that can't be broken down into smaller entities the higher the cohesion of your design.

    So if you look at User class source file and see code that is not directly related to an operation on a user then refactor it

Re^2: The division of (class) labor in OOP
by sri (Vicar) on Jun 06, 2005 at 12:31 UTC
      My impression was that Catalyst is more complex. The documentation to Catalyst says, Catalyst is based upon Maypole, which you should consider for smaller projects. That reinforces my impression. And, I'm sorry, but your article did not dispell it. Yes, you got a lot done in 30 lines of code. But to do that work you need to know how a lot of moving pieces fit together, and there is (to me) some quite surprising use of directives embedded in comments that would take some getting used to.

      Besides, this Maypole intro took less code, with fewer visible moving parts (and less magic) to get an application that looks more useable.

      None of that means, of course, that Catalyst is particularly complex. Indeed, if it does its job, then working with it should be far from complex. But there is a definite learning curve associated with it.

        I would definitely say that both Maypole and Catalyst have a very noticeable learning curve.

        The very reason so much is done in so few lines of code is that so much is going on behind the scenes. Which you need to know about to use it.

        At least Maypole requires a lot of code spelunking to get things done. The silver lining: good code and a nice design.

        /J

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-20 00:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found