wood burning stoves*
The moose likes OO, Patterns, UML and Refactoring and the fly likes maximumly extendable ? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "maximumly extendable ?" Watch "maximumly extendable ?" New topic
Author

maximumly extendable ?

Edward Chen
Ranch Hand

Joined: Dec 23, 2003
Posts: 798
A library will lend books to users, if the user is working "human resource" department, the book that the user checks out will not have any time duration limition


Let me assume
1. we are using agile design,
2. simple and fast
3. maximumly extendable.

OK, if I am a developer, I will do this way

because the spec just requires "human_resource", so I don't need to add a class "department" and its one-to-many relationship. We just need an employee class and database table.

Everything is good, simple and efficient. But we have to realize that maybe in the future the company will change this requirement, ie, not just hr department. We will need a department class and its one-to-many relationship. Therefore we have to leave space in first version so that we will have no pain to extend, especially in hibernate env.

how to achieve this in the case above ? Please share your real experience, not just theory. Thanks.

[changed code-tag of first paragraph to quote-tag, for better formatting - Ilja]
[ October 30, 2006: Message edited by: Ilja Preuss ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
First, I'd probably name the class "User", as that's what it's obviously called by the domain expert.

Second, from just this requirement you don't need a department id, you only need a boolean flag "isWorkingForHumanResources" or something.

And to finally answer your actual question ( ), in my experience by far the best you can do is *not* "leaving space" for a potentially upcoming requirement, for at least two reasons:

- investing resources into features that are needed *now* gives better return on investment than investing them into making the design more complex now with the assumption that it might (or might not!) pay back later, and

- it's quite likely, in my experience, when the requirement actually comes, it will be not exactly like we expected, and the system will already have changed in ways we didn't expect, so the "space" we left for it is unlikely to be very useful.

Instead of "leaving space" now, I'd rather invest into getting really good at refactoring (including refactoring the database) - *that* really pays back manifold!


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Edward Chen
Ranch Hand

Joined: Dec 23, 2003
Posts: 798
Thanks.

If no extendable space, refactoring will be painful: too much and complex changes and unstable risk...

Why I use a string as departmentId, because it is my "space" for extending. In the future, if just a few, ie, less than 10 departments, we just add them as a static final. If more than we expected, then we have to add a new class and new table.

I agree with you that our "space" maybe maybe is useless at all, but we leave there without any hurt.

Thanks
Frank Carver
Sheriff

Joined: Jan 07, 1999
Posts: 6920
I agree with you that our "space" maybe maybe is useless at all, but we leave there without any hurt.

I'd probably disagree with the "without any hurt". Your solution with the constantClass is (IMHO) less readable. It also limits its flexibility by forcing some key logic into data and names rather than behaviour.

I would probably code this more like:



This code is minimal in the sense that it expresses the story as described and nothing else. It is flexible and extendable in the sense that there is a single place to change the rule about who has an unlimited loan without affecting any other classes, fields or methods. And there is no need for a separate "constantClass" - the two fields contain whatever user id and department id the client already uses without any modification. I have used "HR" as an example department id, but that is (obviously) easily changed.

Does that seem reasonable?


Read about me at frankcarver.me ~ Raspberry Alpha Omega ~ Frank's Punchbarrel Blog
Peer Reynders
Bartender

Joined: Aug 19, 2005
Posts: 2922
    
    5
Originally posted by Ilja Preuss:
Second, from just this requirement you don't need a department id, you only need a boolean flag "isWorkingForHumanResources" or something.


Given the requirements wouldn't it make more sense to have a "noDurationLimit" boolean property on the User class and simply map the membership to HR to that property during object instantiation?

In this context it is significant that there are users that don't have a limit - the fact that it members of HR are the ones without the limit seems incidental but not essential.
Michael Feathers
author
Greenhorn

Joined: Aug 24, 2004
Posts: 24
Originally posted by Ilja Preuss:

And to finally answer your actual question ( ), in my experience by far the best you can do is *not* "leaving space" for a potentially upcoming requirement, for at least two reasons:

- investing resources into features that are needed *now* gives better return on investment than investing them into making the design more complex now with the assumption that it might (or might not!) pay back later, and

- it's quite likely, in my experience, when the requirement actually comes, it will be not exactly like we expected, and the system will already have changed in ways we didn't expect, so the "space" we left for it is unlikely to be very useful.

Instead of "leaving space" now, I'd rather invest into getting really good at refactoring (including refactoring the database) - *that* really pays back manifold!


I agree. If you want maximum flexibility, the only space to leave is whitespace. That is the most flexible space of all.

Michael Feathers
http://michaelfeathers.typepad.com
http://www.objectmentor.com
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Edward Chen:
If no extendable space, refactoring will be painful: too much and complex changes and unstable risk...


That's not at all my experience. The simpler the original design, the easier the change, generally.

About the unstable risk: one of the most important things to get an extensible design is to have an extensive, fully automated suite of tests.


Why I use a string as departmentId, because it is my "space" for extending. In the future, if just a few, ie, less than 10 departments, we just add them as a static final. If more than we expected, then we have to add a new class and new table.


How hard would it be to just change it to a String when that future is there? Not much harder than introducing it now, I suppose.

But how do you know that the String will be the right implementation for that feature *plus* all the features that have been implemented in the meantime? (Hint: you typically don't, and it typically isn't.)
Tanveer Ahmad
Ranch Hand

Joined: Sep 20, 2005
Posts: 33
Hi,
I would rather go for the following classes.

class User{
private String userID;
private String deptID;
//
Getters and setters(if any) for the private members.
//
}

abstract class Policy{
public abstract void implementPolicy(User theuser);
}

class HRUserPolicy{
public implementPolicy(User theUser){
if(!theUser.getDeptId.equals("HR")){
enforceTimeLimit();
}
}
}

Please share your coments.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Well, that looks more complicated to me than necessary.

Can you explain *why* you would do that, please?
Tanveer Ahmad
Ranch Hand

Joined: Sep 20, 2005
Posts: 33
Hi,
The thoughts that drove me to opt for the those class are mentioned below.

1. A user class should be nothing but java bean class. A user should never proclaim any thing.
Benefit - This enables the user be more flexible and used again and again.

2. Whether a user is entitled for any benefit is a matter of policy. Policy changes in real business scenario.
Benifit - The idea of having an abstract class just fulfills the above criteria.

*. Regarding the HRUserPolicy class, its just an implementation.

Please share your thoughts.
Thanks
Tanveer
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Tanveer, thanks for sharing your thoughts! Some comments below...

Originally posted by Tanveer Ahmad:
1. A user class should be nothing but java bean class. A user should never proclaim any thing.
Benefit - This enables the user be more flexible and used again and again.


I'm not sure what exactly you mean by "proclaiming", but I'm rather sure that a java bean is allowed to have behaviour.

And I frankly don't see much benefit in reusing a class that doesn't do anything.

In fact your suggestion sounds a little bit like - when followed consequently - it could lead to an Anemic Domain Model: http://www.martinfowler.com/bliki/AnemicDomainModel.html


2. Whether a user is entitled for any benefit is a matter of policy. Policy changes in real business scenario.
Benifit - The idea of having an abstract class just fulfills the above criteria.


Well, I'm sure that once there emerge more policies and/or policies change often, I'd refactor the code so that some kind of Policy class emerges.

But from this one requirement, I can hardly justify the existance. And once I knew more about what kinds of other policies exists, and their change patterns, I would be in a much better position to come up with an appropriate design.

With other words, I can see how your proposed design could be a good one for more complex requirements. I just think that introducing it before we need to implement (let alone even know about) those requirements, would be rather premature.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: maximumly extendable ?
 
Similar Threads
Marshalling XML with Spring (How to handle referenced classes)
hibernate 1:M relationships & cascade
business model to view model anamoly
Design question regarding managing one-to-many relationship...
simple example implementation?