views:

111

answers:

7

This question is regarding object oriented design. It may fit into community wiki.

Usually , when one design a set of classes which communicate with each other through interfaces , he ask himself , what Interfaces should I make? How to abstract various sub-components in the system in order to achieve the design goals.

If we put aside performance and focus more on maintainablilty and productivity and other aspects of design I may ask the following question : Do you think that for every given design problem , there is always a best way to define the interfaces (abstraction) which compose the top layer design of the system?

A: 

No

There is not "one perfect solution" for every software problem.

More than often, two is the majority. Meaning that if you take 10 persons and ask them what a good design would be, if you get two person with the exact same answer it is most certain that they will have a "majority" with 2/10. The more people you get to solve the problem, the more different approaches you'll get.

The point is not about being right or wrong, it is to satisfy criterias such as design quality attributes which are detailed here and enumerated here.

There is a lengthy procedure called the ATAM method which helps to focus on particular aspects of a project. For example, performance (a quality attribute) might be very important for a web server, but irrelevant to a word processor (to some extend, the consideration is there but completely different).

I understand that it is a long and boring paper, but this method is extremely useful. Basic steps are

  1. Check what is important for your software in terms of business requirements
  2. Translate that into quality attributes
  3. Create strategies that will help you ensure the quality attributes.

Point 2 can be :

  • I want my van to be damn fast -> Performance is a very high priority
  • I want this software to exist for the next 25 years -> high maintainability is high priority

Then you'll come up with relevant strategies to achieve those requirements.

Where were we going already? Oh yeah, why do we that for, to discriminate a good design from a bad design.

After those steps, you'll be able to see if your design meet your criterias or not. This goes far beyond having "low coupling, high cohesion" in your classes and such. This is about designing your software with appropriate goals that are relevant for your business

Eric
+4  A: 

There's no absolute good or bad in design. Different designs will give you different trade-offs WRT factors such as: explicitness, flexibility, safety, ease of use, etc.

Here's an interesting quote on this subject: http://javadots.blogspot.com/2008/07/qutoting-allen-holub.html

Itay
I'd vote this up 1000 times if I could. In the programming community, it seems like most zealotry is caused by people focusing on only one of these at the expense of the others. For example, the static vs. dynamic typing debate: The static zealots care only about explicitness and safety, the dynamic zealots care only about flexibility and ease of use.
dsimcha
A: 
  1. I don't think it's possible for there to always be a best way to define interfaces regardless of context (developers, coding standards, etc.)
  2. It's plausible to me that, for a particular context, many or most design problems will have a single best definition for maintainability and productivity purposes.
  3. It's not plausible to me that this will be the case for every design problem. I am fairly certain that design problems can be devised which present multiple, nontrivially differentiated, equivalently valued interface implementations. For it to be otherwise feels like a violation of Gödel incompleteness.
chaos
A: 

I think for every problem there is indeed a "Platonic" solution: in some ideal world, given unlimited time, you will come up with an ideal solution.

In the real world you have to go with what works in the time-frame that you have. You'll need to arrive at that via a consensus (of some sort) with the people involved in the project.

It also sounds like you're ignoring iteration here: the solution that you had at the beginning of the project will undoubtedly be different at the end of the project.

jcollum
+2  A: 

Your question makes a false presumption: that it is possible to identify the set of all design problems in such a way that we can, for each problem, determine the set of solutions, and then compare the solutions to determine, for each problem, a single, "best" solution.

I will point out that it may not be possible even to identify a "design problem" in the real world. I'm not talking about the GoF wprld, where each chapter has a "Design Problem" subheading; but rather the real world where our requirements, designs and code lives. In this world, we may look at a set of classes and see more than one "design problem". We may even find "two design problems and some stuff left over" that we can't clearly identify in GoF.

Additionally, even where it's possible to clearly identify design problems (or to stipulate them), abstractions interact with each other, and with the environment they live in. Even assuming there's a "best" abstraction for a particular problem, that abstraction may not be the best in the given environment.

John Saunders
A: 

Designing is like an multidimensional hill climbing algorithm. If you make good choices you go uphill in most of your dimensions. But if you don't see any more possibilities to improve this does not mean that you have reached an absolute maximum.

Janusz
A: 

Designing tends to be about trading-off costs and benefits. The question gives an example: being prepared to trade performance for maintainability.

For some design decisions I think you will see experienced designers comping up with solutions that have lots of things in common, similar separations of concerns, simmilar apppraoches to encapsulation etc. I like the hill-climbing metaphor though, we might all reach the same impasse :-)

Generally, even considering only maintability, I don't believe that we will have a single agreed answer because we cannot predict the future. Maintainbility is all about enabling some kinds of future change. Our system users tend to be very inventive at finding exactly the set of changes we hadn't foreseen. I wonder whether that's a measure of a successful system, it stimulates users to think about new and exciting features?

djna