Monday, March 27, 2006
Effects of Display Position
There are also many more papers from Mitsubish Electric Research worth reading if you're interested in image recognition, video encoding, HCI, etc.
Tuesday, March 21, 2006
Design, Value, Cost
During the last few business trips, I've spent some time working on a probabilistic estimation tool (see some of my previous postings on this subject). Early on, I decided that the user should be able to see the probability density and distribution, both at the activity level (from some parameters he will set) and at the project level (through a Montecarlo simulation). From previous experience with other tools, I expected Montecarlo simulation to be somewhat slow, so I provided a button to trigger the simulation. Unfortunately, that means the results can get stale if you add or modify activities and you don't run the simulation again. It's unwise to keep stale data on screen, unless you clearly show the user that the data is indeed stale. This makes the design more complex, but classical linear thinking will keep you working hard until you're done.
Alternatively, we may just reconsider the simulation speed. Does it have to be slow? If we could somehow speed it up, it could be run automatically whenever something changes, and we'll never have stale data. Note, however, that it has to be reasonably quick, so that it can be run in the main thread. A separate thread for simulation looks like hard work again.
A first way to gain some speed is through careful coding. Choosing good algorithms and libraries, or writing your own, can be useful as well. I'm using C# for this tool, and it runs reasonably fast. I wrote my own random number generator with the triangular distribution I need; at last, some of that math in Knuth, "The Art of Computer Programming, Vol 2", is proving really useful :-). Right now, an accurate simulation with a small project takes a fraction of a second, and I'm pretty sure I can squeeze a little more performance out of it. This would be enough for small project simulations, but not for larger ones.
Rethinking the user interaction (not simply the "user interface") is another way to remove some hard work. My recent idea is to remove the button and simply provide a combo (or a couple of radio buttons) for the accuracy of the simulation. A Montecarlo simulation takes more time to give back accurate results. Therefore, users could set the accuracy level, and get faster or slower response. If they change the level, the result is updated. There is never stale data on screen: it could be calculated at a less accurate level, but it is never stale. The design is very simple: at the end of the game, the "accuracy" is just a number of iterations.
So here we are: better user experience, easier code. More value, less cost. I kinda like it :-).
Wednesday, March 15, 2006
Organizational Structure
Tomorrow and the day after I'll be teaching my Software Project Management course. From previous discussions, I could foresee that there will be some interest on organizational structure (functional teams, project teams, matrix structure and the like), so I decided to add some custom material. However, the traditional literature on organizational strategy (I've got more than 20 books on the subject) is very theoretical, and definitely not grounded in software, which is an hallmark of my course. Therefore, I took a rather original road, organized around two major tenets.
1) The organizational structure must support the company strategy. Any misalignment will be a cause for friction and inefficiency. An effective, barebone classification of company strategy can be found in Michael Tracy, Fred Wiersema, "The Discipline of Marker Leaders". A couple of papers from Stan Rifkin ("Why Software Process Innovation Are Not Adopted", IEEE Software, July/August 2001 and "What Makes Measuring Software So Hard?", IEEE Software, May/June 2001) give some hints on the relevance of this work for software development.
2) The organizational structure must be aligned with the product architecture. This is a consequence of Conway's Law: "Any organization which designs a system will inevitably produce a design whose structure is a copy of the organization's communication structure" (Melvin E. Conway, "How Do Committees Invent?", Datamation, April, 1968). Convay's paper is one of those classics often quoted and never read, partially because they used to be hard to find. Fortunately, here is an online version. Luke Hohmann ("Journey of the Software Professional", Prentice-Hall) also had an interesting intuition, that is, the best organizational structure for a product is not necessarily fixed: it may change over time (this is probably an agile management frontier right now :-). Finally, some useful information on how the traditional organizational structures (functional, matrix, etc.) performs on software projects can be found in Jack T. Marchewka, "Information Technology Project Management", John Wiley & Sons.
Quite a mouthful, but being a good manager takes much more than technical skills...
For another interesting point of view on organizational structure, see my post An organization consists of conversations.
1) The organizational structure must support the company strategy. Any misalignment will be a cause for friction and inefficiency. An effective, barebone classification of company strategy can be found in Michael Tracy, Fred Wiersema, "The Discipline of Marker Leaders". A couple of papers from Stan Rifkin ("Why Software Process Innovation Are Not Adopted", IEEE Software, July/August 2001 and "What Makes Measuring Software So Hard?", IEEE Software, May/June 2001) give some hints on the relevance of this work for software development.
2) The organizational structure must be aligned with the product architecture. This is a consequence of Conway's Law: "Any organization which designs a system will inevitably produce a design whose structure is a copy of the organization's communication structure" (Melvin E. Conway, "How Do Committees Invent?", Datamation, April, 1968). Convay's paper is one of those classics often quoted and never read, partially because they used to be hard to find. Fortunately, here is an online version. Luke Hohmann ("Journey of the Software Professional", Prentice-Hall) also had an interesting intuition, that is, the best organizational structure for a product is not necessarily fixed: it may change over time (this is probably an agile management frontier right now :-). Finally, some useful information on how the traditional organizational structures (functional, matrix, etc.) performs on software projects can be found in Jack T. Marchewka, "Information Technology Project Management", John Wiley & Sons.
Quite a mouthful, but being a good manager takes much more than technical skills...
For another interesting point of view on organizational structure, see my post An organization consists of conversations.
Labels: article reference, book reference, link, project management, teaching
Tuesday, March 14, 2006
Shrinking LOC by a factor of 50
Although this is a quite remarkable result, that I'm not expecting in every other project, it is neither a miracle nor the byproduct of applying some magic technology or tool. We did it by spending lot of time thinking, much less writing code, taking every opportunity to shrink down the line count, using modern technology but also reusing previous experience. Capitalizing on lessons learned from the previous generation (especially at the database design level) but also avoiding to replicate old concepts (complex hierarchical data stored in relational tables) when modern techniques (XML documents) are better suited.
The project is highly configurable by nature, so quite some time has been spent devising the proper way to express customization concepts in an XML-encoded type system, to create an elegant configuration language instead of the usual mess.
The project is nowhere close to end, and it won't be easy to keep this track record. Still, even when I look at other subsystems (web services interface, the client side) I see huge opportunities to keep the line count down. My rather ambitious goal is to end up with a system way more powerful than the existing one, in 1/10 of the existing LOC. Surprisingly enough, this goal is not popular with everyone involved, but that's something we can live with :-).
As an aside, it's hard not to say that had we taken the easy XP road :-) and concentrated on users story and coding, instead of concentrating on architecture and avoidance of coding :-)), we would now be in the usual mess, a.k.a. hard work. For more on the disappearing effort, see also my post Relationship between Effort and Schedule
Monday, March 13, 2006
Product Trader and Generics
class Test1
{
[Factory( "product1" )]
public static SomeClass1 f()
{
return new SomeClass1() ;
}
}
class Test2
{
[Factory( "product2" )]
public static SomeClass2 f()
{
return new SomeClass2() ;
}
}
A method labeled as Factory doesn't have to be inside the class it creates (although it can). When you want to create a product by name, you just go through a product trader:
SomeClass1 p = (SomeClass1)ProductTrader.CreateProduct( "product1" ) ;
That's pretty much it. There is no need to register anything, no switch/case around, and stuff like that. The product trader will visit the type system the first time it's invoked, find out factories, build a product creators map, and then use the map upon subsequent calls.
Unfortunately, there are (at least) two flaws in this implementation. The first is that the product name is (by design) a string. In many cases a string is useful, but in others (e.g. when decoding messages) an integer would have been better. The other issue is that we need to cast the result of CreateProduct, as that function return type is object.
Obviously, with .NET 2 around, we might be tempted to use generics to solve the problem. However, this is not so trivial. The Factory attribute should be turned into a generic class, to that we could change the parameter from string to anything else. Unfortunately, this is not possible. From the C# 2 specification (20.5.8): "Attribute cannot be the base type of a generic class declaration"; just what we needed :-)). Still, even if we didn't have this problem, removing the cast in the CreateProduct calls would not be trivial at all, unless we settle for the idea that we have a product trader for each product family. This is not really a C# issue, but a more conceptual one, and I guess I'll leave it as the dreaded exercise for the reader :-)). While you're at it, you may want to ponder on the subtle design differences between using a logical product names (as I'm doing here) and labeled creational methods, or using physical product names (assemblyname.classname) and barebone reflection to build the products.
Monday, March 06, 2006
Clone Vs. Assign
Consider how this task could be performed in C++. C++ provides no facilities for cloning, but you can use the copy constructor if class A has one. Not that since we're not making any use of polymorphism, going through a Prototype-pattern-style Clone function would be totally unnecessary: a copy constructor is enough. Later, when you want to copy obj2 over obj1, you can use the assignment operator: C++ doesn't try to hide the difference between an object and a reference (or pointer), so there is no concept of "reference types" and the assignment operator works directly on objects. In many cases, you don't have to define a copy constructor or assignment operator in C++ either, as the compiler can synthesize one for you. Although in C++ 101 you learn that it's often necessary to write your own copy constructor and assignment operator, in many cases a sensible use of smart pointers will make the synthesized version just fine for a shallow copy.
Consider now the same task implemented in C#. There is no notion of copy constructor, but System.Object comes to the rescue and provide a MemberwiseClone method. Since we need a shallow copy, the default implementation of MemberwiseCopy will work just fine, and we don't even have to write a copy-constructor like function. Copying obj2 over obj1, however, is not free. There is no "Assign" function in System.Object. Assigning a reference won't work, and a simple Assign function taking a ref destination parameter won't work either, since obj1 is being referenced by many objects. In this case, I've seen lot of good guys resorting to what I usually call hard work :-). They assign all the fields manually, either inside an A.Assign method or, even worse, in the calling code. Fortunately, there is a better way: in fact, the lack of an Assign method in System.Object is more like a library weakness than a language or platform weakness. Therefore, we can implement our own universal shallow assignment function:
public class ObjectExtensionOf course, the class name is not nice, but this kind of function is the living proof that the idea of having each function residing inside a class is flawed, unless we have open classes, in which case ShallowAssign could be a nice addition to System.Object :-).
{
static public void ShallowAssignment( object dest, object source )
{
Type t = dest.GetType() ;
if( t != source.GetType() )
throw new InvalidCastException() ; // may want to be more specific :-)
FieldInfo[] fields = t.GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ) ;
foreach( FieldInfo fi in fields )
{
fi.SetValue( dest, fi.GetValue( source ) ) ;
}
}
}
Sunday, March 05, 2006
Product Innovation
Alan Cooper: The Insane Are Running The Asylum.
Donald Norman: Emotional Design - Why We Love or Hate Everyday Things.
Jef Raskin: The Humane Interface - New Directions For Designing Interactive Systems.
B.J. Fogg: Persuasive Technology - Using Computers to Change What We Think and Do.
Of course, I will fill the gaps :-), but having some exposure to this material will speed things up. Although those books are not about product innovation per se, they all present an interesting perspective and insights on product development, which will be crucial to effective innovation.
Today, the product is strongly oriented toward what Norman calls the Behavioral level. This is hardly a surprise, as the product is largely coming from a technical-professional mindset. This is quite common: domain experts and engineers usually thrive on the behavioral side. Still, to significantly improve the product, I believe we should find a way to strengthen its Visceral appeal (another of Norman's design levels). We should also reconsider its current role, and make it act more (as Fogg would say) as a social actor.
Product innovation is often a significant challenge. An even bigger challenge, quite often, is convincing the engineers that there is real value in those theories, leading them to leave the system-oriented approach behind, and make them wander freely into untraced territory. So, these two days are going to be challenging, with some chances of also being fun :-).
Back to the books: they all present interesting taxonomies, but they aren't easy to mix. Although Norman's book somewhat acknowledges the existence of the others :-), it doesn't really go to great lengths to merge everything into a unified theory. I would have found that much more interesting than the chapter on robots :-).
Anyway, sooner or later I'll draw a somewhat large table and try to put all what I like of those theories together. While at it, I'll throw in something more, mostly from a business perspective, and a few recipes for innovation taken elsewhere, like Edward De Bono's theories and techniques for lateral thinking, or the Russian "systematic creativity" concepts embodied in Triz, as well as some pearls of wisdom I've got from listening to a Tom Peter's talk ("Circle of Innovation"). And then, of course, we now have several books devoted to innovation itself, like "The Innovation Paradigm Replaced" by Waldo Hitche, and so on...





