Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Design Principles and Code Ownership
November 9, 2002 11:52 PM
|
Artima.com has published Part II of an interview with Martin Fowler, chief scientist at Thoughtworks, Inc. and author of numerous books on software design and process, in which Martin discusses design principles and the spectrum of code ownership.---xj40dkcfea73---Artima.com has published Part II of an interview with Martin Fowler, chief scientist at Thoughtworks, Inc. and author of numerous books on software design and process, in which Martin discusses design principles and the spectrum of code ownership.
http://www.artima.com/intv/principles.html Here's an excerpt: You can almost do this as an exercise. Look at some program and see if there's some duplication. Then, without really thinking about what it is you're trying to achieve, just pigheadedly try to remove that duplication. Time and time again, I've found that by simply removing duplication I accidentally stumble onto a really nice elegant pattern. It's quite remarkable how often that is the case. I often find that a nice design can come from just being really anal about getting rid of duplicated code. What do you think of Martin's comments? |
Posts: 1 / Nickname: chrisliaw / Registered: November 12, 2002 7:10 PM
Re: Design Principles and Code Ownership
November 13, 2002 5:26 PM
|
"There's an intermediate ground that I call weak code ownership. With weak code ownership, there's my code and your code, but it is accepted that I could go in and change your code. There's a sense that you're still responsible for the overall quality of your code. If I were just going to change a method name in my code, I'd just do it. "
The example is more to only-two-developer scenario. What if the team is more then 20? The original author of the source code will no longer know who has changed his code. In a large software project, the main issue to consider is not merely software design, implementation blah blah. It should support by management as well. We don't expect the software project will be self organized do we? By simply allowing everybody to change the code in a large number of group of people does not help in manage the change,especially when the particular group is not 100% adopted the agile/XP programming methodology. Change in this context including who, when and why the changing took place. This kind of info is essential in managing a group of developer in certain situation. Yes, test case will make sure the behaviour after refactoring does not change, but to run the test cases, it is not automatic. It needs the developer to run that test cases to make sure it is correctly refactoring the code. This is not reliable since developer/human tend to forget. If bugs discovered later in later stage let say integration test, there is no way to know what has changed and who changed the code. Knowing this kind of data is important to tackle the problem effectively in the later stage when the schedule is tight and the group is not well managed. I like the idea of XP/agile, but it does not prevent something wrong happening in the management of the software project. XP/agile DOES solve some problem in software life cycle but i don't think it is adequate to prepare the umbrella before the rain is coming. Thank you. |
Posts: 9 / Nickname: mfowler / Registered: November 27, 2002 3:51 AM
Re: Design Principles and Code Ownership
November 27, 2002 9:00 AM
|
> The example is more to only-two-developer scenario. What
> if the team is more then 20? The original author of the > source code will no longer know who has changed his code. > This is not a problem if you are using a source code management system. If you aren't using one of those then you'll have way more problems than all that to worry about. > > Yes, test case will make sure the behaviour after > refactoring does not change, but to run the test cases, it > is not automatic. It needs the developer to run that test > cases to make sure it is correctly refactoring the code. > This is not reliable since developer/human tend to forget. So make it automated. Use Continuous Integration <http://martinfowler.com/articles/continuousIntegration.html> and a tool like Cruise Control <http://cruisecontrol.sourceforge.net/> Martin |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
November 29, 2002 11:56 AM
|
> > The example is more to only-two-developer scenario.
> What > > if the team is more then 20? The original author of the > > source code will no longer know who has changed his > code. > > > > This is not a problem if you are using a source code > management system. If you aren't using one of those then > you'll have way more problems than all that to worry > about. > I agree, but your answer avoids the large issue at hand. Let's quote the whole of the original post.... > In a large software project, the main issue to consider > is not merely software design, implementation blah blah. > It should support by management as well. We don't > expect the software project will be self organized do we? > By simply allowing everybody to change the code in a > large number of group of people does not help in manage > the change,especially when the particular group is not > 100% adopted the agile/XP programming methodology. The problem with "anyone can touch anything" with a larger project is that change can become quickly untrackable (and intractable!) over time, even with source control. With no real boundaries that are "fixed" by the culture, you're encouraging anyone on the team to change anything when they feel it's necessary. Do you trust the judgement of all pairs on your team on all pieces of the code? In my experience, no one person knows all the code in a large app, and some people aren't really qualified to play in certain areas. The reality of large software systems is that there are certain areas where complexity is mandatory - it can't be avoided, XP or no XP. If you take that for granted for a moment, you can see where unrestricted ability to change anything can get out of hand quickly. Particularly when the developers own the unit tests. In a complex area - is the code right, or the unit test, or neither (only the user story gets it right)? You may argue that the user story is too complex, but you cannot always avoid complexity no matter how hard you try (think a financial analytics application, database transaction log, realtime messaging system). > > > > Yes, test case will make sure the behaviour after > > refactoring does not change, but to run the test cases, > it > > is not automatic. It needs the developer to run that > test > > cases to make sure it is correctly refactoring the > code. > > This is not reliable since developer/human tend to > forget. > > So make it automated. Use Continuous Integration > <http://martinfowler.com/articles/continuousIntegration.htm > > and a tool like Cruise Control > <http://cruisecontrol.sourceforge.net/> > This is nice for functional tests, but increasingly today's systems are highly interconnected and include a large number of non-functional tests. For example - your unit test for an order management module isn't worth much if it doesn't exactly mimic the input/output of a 3rd party system you must interact with. To truly test this module you may very well need to interact with this third party system, and this can be very time consuming. Also - think of real time, asynchronous messaging (especially if you combine it with 2PC transactions). Unit tests will be valuable in catching simple internal errors in logic, but it's more important to test the interactions of the total system - and you may not have control of the total system, or its characteristics may be asynchronous in nature. Like others here, I think XP has many good ideas. But too often it shows these ideas in a pristine environment where the developers have complete control. Sadly, this has not been the case in the last 10 projects I've worked on. Asynchronicity, problems of managing multiple developers of varying talent levels, and interacting with complex systems is normal in today's enterprise projects. XP, in my mind, seems very highly adapted towards largely self-contained monolithic applications. > Martin -Mike |
Posts: 9 / Nickname: mfowler / Registered: November 27, 2002 3:51 AM
Re: Design Principles and Code Ownership
November 30, 2002 8:45 AM
|
> Do you trust the judgement of all pairs on your team on
> all pieces of the code? In my experience, no one person > knows all the code in a large app, and some people aren't > really qualified to play in certain areas. The reality of > large software systems is that there are certain areas > where complexity is mandatory - it can't be avoided, XP or > no XP. Agreed. But just because everyone can change any of the code all of time doesn't mean that people will dive into a part of the system they don't understand and change it. In our teams we've found that if you find you need to change something non-trivial in unfamiliar code you pair with someone who knows that bit of the system. Of course this assumes that your developers are professional enough to have some sense of where to go or not go. If your team has developers that are poor enough to do reckless changes then you'll certainly need more controls. Then the right thing would be something like limiting commit privileges or a strict code ownership scheme. But I think there is a significant amount of projects where the developers do (mostly) the right thing. > > > > So make it automated. Use Continuous Integration > > > <http://martinfowler.com/articles/continuousIntegration.htm > > > > and a tool like Cruise Control > > <http://cruisecontrol.sourceforge.net/> > > > > This is nice for functional tests, but increasingly > today's systems are highly interconnected and include a > large number of non-functional tests. For example - your > unit test for an order management module isn't worth much > if it doesn't exactly mimic the input/output of a 3rd > party system you must interact with. To truly test this > module you may very well need to interact with this third > party system, and this can be very time consuming. In those cases I advocate writing a stub for the third party system. Certainly writing the stub is some effort, but it's usually less effort than people fear, and usually has higher payoffs than people realize. Martin |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 3, 2002 8:20 PM
|
> > Do you trust the judgement of all pairs on your team on
> > all pieces of the code? In my experience, no one > person > > knows all the code in a large app, and some people > aren't > > really qualified to play in certain areas. The reality > of > > large software systems is that there are certain areas > > where complexity is mandatory - it can't be avoided, XP > or > > no XP. > > Agreed. But just because everyone can change any of the > code all of time doesn't mean that people will dive into a > part of the system they don't understand and change it. In > our teams we've found that if you find you need to change > something non-trivial in unfamiliar code you pair with > someone who knows that bit of the system. > If it's a 6 or 7 figure project, do you really want to gamble on the judgement of individual programmers? Does self-organization really work when you have hundreds or thousands of user stories in the final product? I personally believe in loose ownership. There should be definite "experts" in various areas of the code, but any developer should be allowed to make changes as needed. The difference from straight XP isn't so much physical as psychological. You know there's a guy that knows a particular sub-system inside and out, and that guy (or gal :-) is far less likely to screw up the more complex aspects of the code. The idea of letting developers sort it out and collectively own everything seems rather naive. And this goes back to my original question that you've kind of avoided - are all pairs equal? Given a culture of anyone-can-change anything, what happens when you stick a new guy (maybe very skilled, but new nonetheless) on a hunk of code that's been refined over many months? I know in alot of cases the real expert in those areas isn't going to be very interested in pairing up with someone who's only going to slow him down. More extensive documentation would be a boon here in easy people in - but XP appears to frown on that, too (in fact, Martin, you seem to oppose even the idea of shaping semi-concrete interfaces and publishing their definitions out to the rest of the group). > Of course this assumes that your developers are > professional enough to have some sense of where to go or > not go. If your team has developers that are poor enough > to do reckless changes then you'll certainly need more > controls. Then the right thing would be something like > limiting commit privileges or a strict code ownership > scheme. > Let's be candid here. We can't pick our colleagues, and alot of people who are only so-so came into the biz during the dot-com rush. To say otherwise is to gloss over a serious issue in the IT world. If you take this at face value, then your best bet is to get the most out of everyone on the team, and to hell with software ideologies. I may not be sanguine with the performance of some of my staff, but I can almost never do what XP suggests and just kick someone off the team. It's not in my control. And I can't have them sitting on their thumbs, or wrecking things that used to work fine. A way needs to be found to make everyone on a team productive within their capabilities. This is difficult in XP, where equality is promoted above almost everything else. Pairs don't help here either. XP seems to ignore psychology - to its detriment. Some people just suck at pair programming - but are otherwise very good and very productive. I do not wish to kick someone off a team just because he doesn't work well in pairs. Likewise - while I believe in mentoring, I don't believe in saddling a senior person with a novice in the name of collective code ownership. Risk, reward, and work all come into play here, and again is a part of psychology. Many senior developers will see pairing with an individual of lesser skills as a punishment - and they're sort of right. What I want to see is XP to acknowledge that there is not one level of programmers - or two, or three, or fifty. People are truly individuals - and that's why collective ownership doesn't work on larger systems. > But I think there is a significant amount of projects > where the developers do (mostly) the right thing. > The number of qualifiers in the above statement is kind of telling, don't you think? Significant and mostly? I think XP needs to recognize that not all college grads will eventually turn into wizards, and that not all wizards are benevolent and kind old geezers who love to teach up and coming youngsters. Software is about people, and people are remarkably varied. The whole point of project managemen is to work with the people you've got to make a system work. > > > > > > > So make it automated. Use Continuous Integration > > > > > > <http://martinfowler.com/articles/continuousIntegration.htm > > > > > > > and a tool like Cruise Control > > > <http://cruisecontrol.sourceforge.net/> > > > > > > > This is nice for functional tests, but increasingly > > today's systems are highly interconnected and include a > > large number of non-functional tests. For example - > your > > unit test for an order management module isn't worth > much > > if it doesn't exactly mimic the input/output of a 3rd > > party system you must interact with. To truly test > this > > module you may very well need to interact with this > third > > party system, and this can be very time consuming. > > In those cases I advocate writing a stub for the third > party system. Certainly writing the stub is some effort, > but it's usually less effort than people fear, and usually > has higher payoffs than people realize. > I think you miss the point here - you're duplicating here. You have the real system, and something mimicking the real system. The problem is that it's extremely easy for the two to get out of sync. Just like duplicate code is bad, stubbing out a system indefinitely is just as bad and can lead to endless confusion. Following your advice, I can pass my unit tests with flying colors but still fail at integration/QA time - because my stub doesn't match reality. Just like relying on unit tests as a front-line defense is bad, so is relying on stubs written by the same developer who wrote the stub. It's self-referential and not based on the realities of the whole system. No one cares if you work with your stub - only if it works with the real system. The stub is useful if you don't have a real system, but should be discarded at the earliest opportunity. > Martin -Mike |
Posts: 9 / Nickname: mfowler / Registered: November 27, 2002 3:51 AM
Re: Design Principles and Code Ownership
December 3, 2002 10:31 PM
|
This is dragging into a usual pro/con XP debate - and I really don't want to go there. I've seen XP's techniques work well but I'm not inclined to push them on people who don't fancy them. If you're interested in discussing this further I'd suggest one of the XP groups.
Martin |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 4, 2002 7:58 AM
|
> This is dragging into a usual pro/con XP debate - and I
> really don't want to go there. I've seen XP's techniques > work well but I'm not inclined to push them on people who > don't fancy them. If you're interested in discussing this > further I'd suggest one of the XP groups. > Well, the interview was billed as "Fowler gives his views on many topics, including refactoring, design, testing, and extreme programming", and this is a discussion forum based on that interview. How could a discussion on the pros and cons of XP be out of line here? Likewise a discussion of levels of explicitness in code. One might say that you brought you it up :-/ What is the point of this forum if it isn't to discuss points made during the interview? > Martin -Mike |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
November 29, 2002 2:57 PM
|
On explicitness:
I see your point in general on generic, data driven solutions being more complex than explicit hard-coded classes. But in the spirit of Extreme Programming, you seem to have taken it to Extremes! Is your example of discount plans from the IEEE article really meant to be indicative of what you mean? I certainly hope not. When you talk of the generic solution, you state: "With the generic case you must look at the generic code and the setup code, and it's hard to see what's happening - and even harder with more complicated bits of behavior". I don't wish to sound offensive - but are you for real here? A developer who considers your table-driven code hard should not be creating an order system - I see a page of code for the hard-coded stuff vs. a page and a half for the generic. And let's think of real businesses for a moment - how many are going to truly have hard-coded discount levels (down to hard coded discount numbers)? You go on to say: "Of course, we can extend the generic order without "programming", but I'd argue that configuing that data is a form of programming". Sure - Enterprise Java development and Excel macros are both programming. But the former is going to cost the customer a hell of a lot more money. If you go way, way back - say to the 80's - you'll find that data driven code was a liberating factor in software development. Customers were no longer beholden to developers code every little bit of behavior - they could actually configure things as they liked it. You sound like you're advocating a giant leap backward. Look - over-generalization is a real problem in our industry. People are trying to create shuttle orbiters when the user wants a skate board. But your advice appears knee-jerking in the opposite direction - dumbing down developers to writing hard-coded junk and earning 6 figures while doing it. Let's look at your problem domain again. No order system is ever, ever going to live with 3 hard coded discounts. You don't need user stories or use-cases or going out for beers with the sales man to predict that. What you've done is shown a "design" written by a comp sci graduate out of college that any decent designer knows has to be re-written later. In this case, the development time is probably measured in terms of an extra hour or so. What will eat more time in the long haul - refactoring hard-coded behavior (that's probably grown from 3 discounts to 10, all explicitly coded in classes), or starting with a light-weight generic discounter of modest ambitions that can be easily expanded over time? Or is the purpose of XP just to get the consultants out the door quick at the end of the engagement - and leave the real permanent developers back at the ranch to pick up the "just-in-time, simple-as-CS-211, guaranteed 100% unconfigurable" code base? I'm really trying to understand here, not just throw quips out. Data driven programs have freed customers from having to wait a week for a developer to change a 15 to a 5 - and now you're advocating we go back to that? Are your developers hiring out at $15 an hour, making such changes as affordable as pointing a junior QA person to an XML file? Or, perhaps, does peer-programming and developer-written unit tests and index-card user stories and napkin designs only work on tiny systems with novice developers? Is the cost of allowing anyone to do anything anytime dumbing down the code base to the lowest, greenest programmer on the team? Perhaps, in the spirit of simplicity, we should become more leery of RDBMS products and go back to btrieve and VSAM files and dBase II? -Mike |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
November 29, 2002 3:23 PM
|
I know, it's rude to reply to self, but a quick link:
http://www.thoughtworks.com/library/index.html Scroll down and see the PDF "Reconigizing and Responding to "Bad Smells" in XP". A very thoughtful article from ThoughtWorks (of all places) on how slavishly following XP on a real enterprise application can lead to trouble - and how thinking ahead and using your common sense is always the right thing to do. -Mike |
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: Design Principles and Code Ownership
November 30, 2002 1:53 PM
|
> Look - over-generalization is a real problem in our
> industry. People are trying to create shuttle orbiters > when the user wants a skate board. But your advice > appears knee-jerking in the opposite direction - dumbing > down developers to writing hard-coded junk and earning 6 > figures while doing it. Let me give you a different example for which you may or may not prefer the explicit solution. I once did a design review for a very nice fellow who at one point in the review introduced me to his Manager interface. (I think that's what it was called.) It looked something like this:public interface Manager { public Map accept(Map params); } The designer explained that he had a bunch of classes in his design that implemented this interface. He pointed out the advantage of this approach as primarily being flexibility. It was easier for him to make changes such as passing in or returning an extra parameter. I was a bit stymied as to how to convince him that explicit method names and class hierarchies were useful. But I attempted to explain that the reason that I prefer to design explicit type hierarchies containing explicit method names is because that makes the code easier to understand. I think of types as opportunities to communicate concepts to developers. When I see the word Map in his interface, I know what that means. When I see Map.add() in a piece of code, I know what that means. But if I saw a Manager being used in his code, I would have to dig further to figure out what it was doing.The other thing that struck me about his interface was that it looked just like a Java incarnation of the HTTP interface. You pass data in and you get data back. Any kind of data can go back and forth. Now I doubt many would argue that HTTP is a bad design. HTTP is indeed very flexible. Look at all the kinds of things people have done with it. And even though HTTP isn't as explicit as a hierarchy of individual protocols each with a focused area of responsibility and limited set of functions, HTTP is very widely used by a lot of developers to do a lot of things. What this experience led me to realize was that the main value of designing type hierarchies is communicating to developers. Types with focused areas of responsibility and limited sets of methods help programmers understand APIs and code. I think that's the point Martin is trying to make in his To Be Explicit article. Explicitness isn't the only thing that helps programmers understand APIs and code. Making code easy to understand isn't the only thing we should worry about when we program. But given that the most expensive aspect of development is usually the developers' time, improving developer productivity is important, and explicit APis and code in general helps developer productivity. |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 3, 2002 8:50 PM
|
>
> Let me give you a different example for which you may or > may not prefer the explicit solution. I once did a design > review for a very nice fellow who at one point in the > review introduced me to his Manager > interface. (I think that's what it was called.) It looked > something like this: > > public interface Manager { > > public Map accept(Map params); > } > > The designer explained that he had a bunch of classes in > his design that implemented this interface. He pointed out > the advantage of this approach as primarily being > flexibility. It was easier for him to make changes such as > passing in or returning an extra parameter. > At first blush this appears to be a simple matter of over-generalization. In fact, it's so generic that it could do anything. I agree this is a bad approach, and a more constrained API is the way to go. Certainly, over generalizing is just as bad as hard coding everything. This is why every method isn't: Object doit (Object stuff); and it's also why you don't say: int interestRate = princ * 32 + 1; Both are bad. I disagree with Mr. Fowler's approach because I believe he goes too far towards the latter - hard coding business logic and constants in code that have no business being hard coded. [....] > > What this experience led me to realize was that the main > value of designing type hierarchies is communicating to > developers. Types with focused areas of responsibility and > limited sets of methods help programmers understand APIs > and code. I think that's the point Martin is trying to > make in his To Be Explicit article. I agree to a point - but if nothing else the article is a poor example. I can create an API that supports configurable, generic discount plans in a way that guides developers and also gives flexibility. But I certainly don't want to take the explicit approach and write code that says "The blue plan gives a 15% discount". When I read the Explicit article, what I see is "developers are so stupid that you should avoid data-driven solutions whenever possible". I'm sorry, but that's how it reads to me. > Explicitness > isn't the only thing that helps programmers understand > APIs and code. Making code easy to understand isn't the > only thing we should worry about when we program. But > given that the most expensive aspect of development is > usually the developers' time, improving developer > productivity is important, and explicit APis and code in > general helps developer productivity. I see it 180 degrees the other way. Development time is so expensive that developers shouldn't hard-code business behavior when it makes sense not to. If your system needs discount plans, I don't want a programmer writing classes to describe it. I want a couple of database rows, XML, or whatever to define it. That way developers are spending their time writing real code that does real work, not doing the work of administrators. -Mike |
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: Design Principles and Code Ownership
November 30, 2002 0:50 PM
|
> "Of course, we can extend the generic order without
> "programming", but I'd argue that configuing that data is > a form of programming". > > Sure - Enterprise Java development and Excel macros are > both programming. But the former is going to cost the > customer a hell of a lot more money. > > If you go way, way back - say to the 80's - you'll find > that data driven code was a liberating factor in software > development. Customers were no longer beholden to > developers code every little bit of behavior - they could > actually configure things as they liked it. You sound > like you're advocating a giant leap backward. > I think you've blended two kinds of change here: changes made by the software provider and changes made by the customer. When it comes to enabling customers to make changes, you're talking about configuration. How configurable should you make a piece of software? I think that is an important question, but it is not the same question as: how explicit should you make the code of a piece of software? I tend to be frugal when deciding what to make configurable, because I see each one of those configurable pieces of data as a feature that may have to be explained to the user. Configuration parameters are part of the user interface. Though configuration is usually a less-used part of a user interface, it still adds complexity. You have to balance making your system configurable with making it easy to use. If there is something I am darn sure the user will want to configure, then I make it configurable. But if I'm not sure, I don't make it configurable, because I want to make the configuration as easy as possible. If it turns out customers want to configure one of those parameters I wasn't sure about and left out, then they will yell at me and I'll make it configurable in the next release. I take a similar approach when deciding to write explicit code or data-driven code. I see data-driven code kind of like configurable code, where the users doing the configuration are other programmers on the team. My friend Matt Gerrans is always chewing me out for not putting parameters in INI files where they are easy to change without compiling. I tend to hard-code data as constants more often than put them in external files as parameters. The reason I do that is because I see pulling things out into INI files as not being free. Yes it makes things more configurable, but I think it also adds complexity. I can't adjust the parameter right in the source file where it is used. I have to go chasing to find the right named parameter in the right INI file. I think of developers as users of my interfaces and code, and I try and balance ease of configuration with ease of understanding and ease of use for them. I'm curious what kind of code others prefer to see. I probably tend to write code that I myself find easiest to read, understand, and work with. But maybe you prefer to see more configurable code. How you decide when to hard code a parameter (hopefully with a constant) versus make it developer-configurable via an external file? When do you prefer to see data-driven code versus more conversationally explicit code? |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 3, 2002 8:41 PM
|
> I think you've blended two kinds of change here: changes
> made by the software provider and changes made by the > customer. > > When it comes to enabling customers to make changes, > you're talking about configuration. How configurable > should you make a piece of software? I think that is an > important question, but it is not the same question as: > how explicit should you make the code of a piece of > software? > A piece of software does not have to necessarily be user-configurable to be generic. Your "tables" can be internal to the code. The idea is to take care of today's needs, but also pave the way for more flexible configuration in the future. > I tend to be frugal when deciding what to make > configurable, because I see each one of those configurable > pieces of data as a feature that may have to be explained > to the user. Configuration parameters are part of the user > interface. Though configuration is usually a less-used > part of a user interface, it still adds complexity. You > have to balance making your system configurable with > making it easy to use. I agree. However, Mr. Fowler chose a piece of business logic to make his point, specifically discount plans and rates. Who here honestly believes that this would ever stay hard-coded in the code for any length of time? > If there is something I am darn > sure the user will want to configure, then I make it > configurable. But if I'm not sure, I don't make it > configurable, because I want to make the configuration as > easy as possible. If it turns out customers want to > configure one of those parameters I wasn't sure about and > left out, then they will yell at me and I'll make it > configurable in the next release. > I have a somewhat finer approach, and I've seen it used extensively elsewhere. In my approach, there is system-level configurability, and items which are directly configurable by the user. The latter piece needs extensive instructions, and possibly a fancy user interface, so that the customer may make changes. The former is just as configurable, but hidden from the user. And such "hidden" configurations have saved my ass on a number of projects. > I take a similar approach when deciding to write explicit > code or data-driven code. I see data-driven code kind of > like configurable code, where the users doing the > configuration are other programmers on the team. My friend > Matt Gerrans is always chewing me out for not putting > parameters in INI files where they are easy to change > without compiling. I tend to hard-code data as constants > more often than put them in external files as parameters. > The reason I do that is because I see pulling things out > into INI files as not being free. Yes it makes things > more configurable, but I think it also adds complexity. I > can't adjust the parameter right in the source file where > it is used. I have to go chasing to find the right named > parameter in the right INI file. I think of developers as > users of my interfaces and code, and I try and balance > ease of configuration with ease of understanding and ease > of use for them. > I've been writing configurable code for so long that the complexity no longer seems all that difficult for me - but of course others may differ. The reason I go down that route is that I can't forsee all possibilities. Hard coding seems great until a production problem crops up. In my world, those problems can often be resolved by an expert tweaking the right parameter and restarting the process. In the world you describe, you need a coding/QA/deployment cycle. > I'm curious what kind of code others prefer to see. I > probably tend to write code that I myself find easiest to > read, understand, and work with. But maybe you prefer to > see more configurable code. How you decide when to hard > code a parameter (hopefully with a constant) versus make > it developer-configurable via an external file? When do > you prefer to see data-driven code versus more > conversationally explicit code? I personally create explicit code when under severe time pressure, when I don't understand the problem domain very well, or when the parameter is so "natural" that's its wildly improbable that someone would choose something else. I also go explicit when there is only one "instance" of it, or two. If there are three or more variations, that spells "data driven" to me. -Mike |
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: Design Principles and Code Ownership
December 4, 2002 9:57 AM
|
> I've been writing configurable code for so long that the
> complexity no longer seems all that difficult for me - but > of course others may differ. The reason I go down that > route is that I can't forsee all possibilities. Hard > coding seems great until a production problem crops up. > In my world, those problems can often be resolved by an > expert tweaking the right parameter and restarting the > process. In the world you describe, you need a > coding/QA/deployment cycle. > The funny thing is that the reason I prefer to not make things configurable unless I know already they need to be configurable is that "I can't forsee all the possibilities." I agree with you that if a production problem crops up that can be solved by tweaking a configuration parameter, then you've gotten a good return on your investment of making that parameter configurable. But what the the 300 other parameters you made configurable that never needed to be configured? What about the 3 parameters you didn't make configurable that did need to be configured? One way to deal with our inability to predict the future is to make things as generic and/or configurable as possible. Another way is to just solve the specific problem at hand and add functionality in the future as it becomes required. I see these as two ends of a spectrum, not an either or choice. I get the sense that the XP camp advocates never doing anything beyond solving the specific problem, and I do find that advice to be a bit extreme. But my own way of dealing with uncertainty (the inability to see the future) is to lean heavily towards the specific solution end of the spectrum. I am conservative about adding any kind of functionality or genericity that I don't know I actually need right now. I do it sometimes, but usually I don't. Because I'm not good at predicting the future, the risk is high that I won't get a sufficient return on the investment of time spent putting in generic functionality that I don't actually need right now. |
Posts: 9 / Nickname: mfowler / Registered: November 27, 2002 3:51 AM
Re: Design Principles and Code Ownership
November 30, 2002 8:54 AM
|
> On explicitness:
> > I see your point in general on generic, data driven > solutions being more complex than explicit hard-coded > classes. But in the spirit of Extreme Programming, you > seem to have taken it to Extremes! Well, I would argue that you've taken one part of my discussion to extremes. As I said in the article The generic case works when you have dozens of discounters. In such cases, the volume of code becomes a problem, while greater volumes of data are less problematic. Sometimes a well-chosen data-driven abstraction can make the logic collapse into a much smaller and easier-to-maintain piece of code. I'm not saying data driven approaches are bad. I'm saying that data driven approaches reduce explicitness which is a bad thing. But there other forces in play and explicitness doesn't trump them all. However explicitness has to be considered, and I think sometimes it isn't considered by more able designers. I'm also quite aware that discounting is often much more complex than my example, but I assumed the reader would realize that I need a simple example because a column doesn't have room for a really complex one. Martin |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 3, 2002 8:31 PM
|
> > On explicitness:
> > > > I see your point in general on generic, data driven > > solutions being more complex than explicit hard-coded > > classes. But in the spirit of Extreme Programming, you > > seem to have taken it to Extremes! > > > Well, I would argue that you've taken one part of my > discussion to extremes. As I said in the article The > generic case works when you have dozens of discounters. In > such cases, the volume of code becomes a problem, while > greater volumes of data are less problematic. Sometimes a > well-chosen data-driven abstraction can make the logic > collapse into a much smaller and easier-to-maintain piece > of code. > Agreed. However - I would not say "dozens". Usually, once you hit three or four your internal alarms should go off that you're hard coding things that shouldn't be hard coded. And you can't discount domain knowledge, either. In some situations it is blindingly obvious that a generic solution will be needed before you're truly done. Staring that solution early and growing is going to be a heck of alot easier on everyone than starting with a hard coded solution and trying to switch over later on. > I'm not saying data driven approaches are bad. I'm saying > that data driven approaches reduce explicitness which is a > bad thing. But there other forces in play and explicitness > doesn't trump them all. However explicitness has to be > considered, and I think sometimes it isn't considered by > more able designers. > I'm forced to completely disagree. One given instance of an explicit piece of code is easier to understand. "N" instances of code 99% the same is not easier to understand - even it's only three instances - because to understand the whole mechanism you have to look at all the instances. Worse - you've still overlooked the cost and effort of programmer time. Explicit solutions always need a developer to make any sort of change. That's not only inflexible, but expensive. In NYC, where I work, developers routinely get 6 figures or just below. The last person I want fiddling with a discount rate is a programmer. > I'm also quite aware that discounting is often much more > complex than my example, but I assumed the reader would > realize that I need a simple example because a column > doesn't have room for a really complex one. > I understand. But whereas you advise to be explicit until it doesn't work, and then attempt to change over to a generic mechanism if warranted at a later date, I advocate starting with a lightweight generic mechanism and growing it over time. The advantage of the latter approach is that it gets _everyone_ on the team (QA, project management, customers) used to what's configurable and what's not. Plus, while the intial generic mechanism may not be workable 3 months down the road, it's at least set the stage for future work. And the initial design is going to get more right than wrong, despite what you've stated. Refactoring is still important to make sure your solution stays appropriate - but I'd much rather refactor the generic solution than try to pull 4 divergent explicit solutions into one down the pike. > Martin -Mike |
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: Design Principles and Code Ownership
December 4, 2002 9:36 AM
|
> I'm forced to completely disagree. One given instance of
> an explicit piece of code is easier to understand. "N" > instances of code 99% the same is not easier to understand > - even it's only three instances - because to understand > the whole mechanism you have to look at all the > instances. > That's true, but I don't think that's the kind of "explicitness" we are talking about. Perhaps you have three methods whose names each explicitly say what they do. That makes code calling them more explicit. But if those methods do 99% of the same thing, then they that 99% code should be factored out as one private helper method (also with an explicit name). Now it is a judgement call whether to collapse the three public methods into one public method with a parameter. The point of the explicitness argument I think is simply that part of the way you make that judgement is by asking yourself what appoach (three methods versus one) will make the client's code easiest to read and understand, and that method names that explicitly say what they do tend to improve readibility. > Worse - you've still overlooked the cost and effort of > programmer time. Explicit solutions always need a > developer to make any sort of change. That's not only > inflexible, but expensive. In NYC, where I work, > developers routinely get 6 figures or just below. The > last person I want fiddling with a discount rate is a > programmer. > I wouldn't equate explicit with non-configurable. You can have a highly configurable system from the outside whose code on the inside is explicit. Explicit doesn't mean you don't use data. It just meanst that when I look at your code it kind of tells me what it does by the way you've partitioned things and named them. |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 4, 2002 7:25 PM
|
> > I'm forced to completely disagree. One given instance
> of > > an explicit piece of code is easier to understand. "N" > > instances of code 99% the same is not easier to > understand > > - even it's only three instances - because to > understand > > the whole mechanism you have to look at all the > > instances. > > > That's true, but I don't think that's the kind of > "explicitness" we are talking about. Perhaps you have > three methods whose names each explicitly say what they > do. That makes code calling them more explicit. But if > those methods do 99% of the same thing, then they that 99% > code should be factored out as one private helper method > (also with an explicit name). Now it is a judgement call > whether to collapse the three public methods into one > public method with a parameter. The point of the > explicitness argument I think is simply that part of the > way you make that judgement is by asking yourself what > appoach (three methods versus one) will make the client's > code easiest to read and understand, and that method names > that explicitly say what they do tend to improve > readibility. > I concur completely in those areas. I think part of the mismatch is not based on the interview, but one of the supporting documents (Mr. Fowler's essay on explicitness). In that document the view is very much (and this is a paraphrase, not a direct quote) "do exactly what the user story says, do not extrapolate, and make it as concrete as possible". The last example given is the discount plan example, and I disagree most heartily with that example. There, the discussion is about a common business component (discount plans), of which there are several variations (in the example, three). In that sort of situation the explicit code is a cop out. You're making someone's life more difficult down the road on purpose so you can get this iteration in with minimal work. I think that's wrong - not morally, but in terms of overall work on a project. In short, the coder is just _asking_ for trouble by being explicit in that sort of situation. > > Worse - you've still overlooked the cost and effort of > > programmer time. Explicit solutions always need a > > developer to make any sort of change. That's not only > > inflexible, but expensive. In NYC, where I work, > > developers routinely get 6 figures or just below. The > > last person I want fiddling with a discount rate is a > > programmer. > > > I wouldn't equate explicit with non-configurable. You can > have a highly configurable system from the outside whose > code on the inside is explicit. Explicit doesn't mean you > don't use data. It just meanst that when I look at your > code it kind of tells me what it does by the way you've > partitioned things and named them. I don't think that's so much as explicit as just plain well written. If you re-read Mr. Fowler's essay I think you'll see that he's directly arguing against data-driven code unless a powerful argument is made for it. Explicit there means very, very explicit, to the point of hard-coding your discount rate for the "blue plan" (or whatever) directly in your code at 15%. Perhaps the example was just a really bad one from my perspective, having seen precisely such code push projects past deadlines and over budget because someone took a very, very short term view of the requirements. It's even worse in the XP sense. Given rotating pair programmers working on different stories at different times, the developer is in effect foisting the effort to make the code configurable on some other developer at a later time - when the system is more complex and by definition harder to refactor. See the essay by Mr. Fowler's company which dissects a large project which took the XP approach, and how following requirements literally at every stage got them in to trouble. The problem I really have with this flavor of expclitness is the concept of religiously following the requirements of this iteration (possibly out of many, many iterations) and refusing to apply any forsight at all. Mr. Fowler can assert all he wants that it works out somehow in the end, but real case studies say precisely the opposite. -Mike |
Posts: 9 / Nickname: mfowler / Registered: November 27, 2002 3:51 AM
Re: Design Principles and Code Ownership
December 4, 2002 8:03 AM
|
We've pretty much run this thread dry. Summing up I'd say that you are inclined to do data driven approaches much earlier than I am. Clearly also my choice of example hit a sore point - for which I apologize but defend myself by saying that any example simple enough to follow is going to be simplistic.
There's also a difference of opinion on ease of refactoring into a data driven approach. I find it quite easy to write very concrete code and rapidly generalize it - to a data driven style if needed. You would prefer to start data driven from the beginning. Martin |
Posts: 11 / Nickname: mspille / Registered: November 29, 2002 6:44 AM
Re: Design Principles and Code Ownership
December 4, 2002 7:38 PM
|
> We've pretty much run this thread dry. Summing up I'd say
> that you are inclined to do data driven approaches much > earlier than I am. Clearly also my choice of example hit a > sore point - for which I apologize but defend myself by > saying that any example simple enough to follow is going > to be simplistic. > Reading your most recent interview, I'd say our approaches match somewhat, but differ mostly in timing. I, too, always start out with an explicit approach in the beginning. This helps me wrap my mind around the problem in full and really test out all the boundaries of the problem space. The difference is that I'll rarely release that code. It's my "fooling around code". Once I've gotten something working with the bailing wire and duct tape, I throw it all away and write a more appropriate solution from scratch. It's not so much refactoring as writing a proof of concept to figure things out, throwing 90% of that out, and then writing the real thing. As you mentioned, this seems wasteful but in fact wonderfully concentrates the mind and figures out solutions to problems fast. But I think it's important not to release that conceptual code but something that benefits from what you learned. From what I've read, you seem comfortable releasing stuff into an iteration that has alot of "explicitness" in it, and leave it to a later time to refactor when more information becomes available. I've tried that approach, and it's burned me more times than I care to admit. Taking the time to look ahead just one or two iterations, and applying hard-won business knowledge from past projects, means make the code a bit more configurable up front to avoid several painful refactors down the road. > There's also a difference of opinion on ease of > refactoring into a data driven approach. I find it quite > easy to write very concrete code and rapidly generalize it > - to a data driven style if needed. You would prefer to > start data driven from the beginning. > I think the difference is deeper than this. You have repeatedly stated that refactoring is an on-going process that never stops (yes, this is a paraphrase). I prefer to rapid prototype a proof, chuck it, re-write and then be satisified with the result until several iterations later when the well-docmented "pain factor" gets too high. In my own projects, constant refactorings are not practical because all the details of a given component or sub-system do not stay fresh in my mind indefinitely. Because of this, constant refactoring means I'm going to be re-structuring code that's a bit fuzzy to me - and I believe this is a bad thing. In short, I prefer to take costs up front. If I make a mistake doing that from time to time, fine. But most of the time that up-front work pays off down the road when crunch time comes and final deliverables loom. In short - never, ever put the hard work off for last, because that's when you'll have the least amount of time to do it. > Martin -Mike |