Jason Mauss' Blog Cabin

Because someone's got to do the dirty work

Blog-Flair

Blogroll

Links

How to determine object responsibility?

Right now I'm working on a project that requires its own custom registration/authentication system and it got me thinking about object responsiblity and OO design.

I'll pose this question and see what kind of opinions everyone has.

I have a "User" class with the usual properties - first name, last name, email, etc.etc.

Should my User class have a method named "Register" where the User object is responsible for knowing how to register itself - OR - should I have a 'Register' method in say, some kind of security class that accepts a User object and uses the property values to register the User? I've abstracted all the direct DB interaction code into a data access library but where the Register method belongs - in terms of good standard OO design - still has me thinking. I might have to dig up my copy of "Object Thinking". It's been a while since I read it but I remember it having good stuff on topics like this.

What do you think the right design is?

Comments

Xerxes said:

i've seen a lot of different architectures over the years, and i've found that there's no one "right design - most good design techniques seem to work well...Having said that, there are a lot of bad ways of doing it too ;)

Under a pure BusinessObject model, you'd implement it using the former style - all logic related to operating on the User is contained within the user. Downside with that approach is that your User object becomes quite heavy. In some cases you'll find that you cant instantiate an object without also instantiating other dependencies. On the positive side however, you've achieved 100% OO encapsulation. As a side note, if you subclass User and create a SpecialUser, you can override the save behaviour unique to this new class.

If you implement it using the latter, you're still achieving similar results, and you're still ensuring separation of concerns, but you're allowing for other objects which may inherit from User to also use that core functionality without being able to change it, as in the example above. eg: The SpecialUser could also be saved under this approach. If the intention was that the SpecialUser cannot be saved, then you'll now have to implement that logic in your Security class, rather than being able to override the implementation of SpecialUser. If you do go down this approach, I'd recommend passing interfaces rather than classes as method arguments. Using interfaces will make it easier to mock test your code.

just my $0.02

# July 17, 2008 6:52 PM

Ian Qvist said:

It depends on the demands of the application. Should you focus on extensibility? (Service pattern, modules, third party authentication systems) Consistency? (Factory pattern) or something else?

I would personally base my design on extensibility. Later you might switch to something like OpenID for authentication and that would be easier if you had a clear interface between your application and the authentication mechanism.

Abstract away the authentication part. Make sure to use interfaces (as minimal as possible. By that I mean lightweight) to define a low coupled architecture between application and authentication.

As for the registration part, do as you see fit. I would do the same thing as with the authentication part.

BTW: Why not use a DAL (Data Access Layer) generation tool such as Subsonic, NHibernate or LINQ?

# July 17, 2008 8:20 PM

Andrew said:

According to Bertrand Meyer’s “Object-Oriented Software Construction”, the essence of object-oriented is that instead of a bunch of functions, and a bunch of data, pieces of data are grouped together with the functions that operate on them into things called “objects”.

So if your register method doesn’t actually operate on data in the user object -- it uses the user data as input but does it’s actual work on a central database -- then the register() method doesn’t belong in the user class.

# July 24, 2008 5:24 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)