eyt*

Find your next scenic drive!

November 7, 2004

Some Environmental Antipatterns...

The October issue of ACM's Queue has an interesting piece by Phillip Laplante, which discusses some anti-patterns in our industry. These antipatterns and more are going to be published in the book Antipatterns for IT, co-authored by Colin Neill.

The first one discussed is called, “The Burning Bag of Dung” and relates to the prank of lighting up a bag of dog-doings on a neighbours porch, ringing the door bell, and fleeing. We have all have been left with some such bag at some point of our lives, as Phillip enumerates, such as poor software development practices, and usually addressing such problems is not easy. He does present an example and some ways to resolve the issue, but these are rather specific to the example.

The next antipattern described is Founderitis, which describes an organization where the founder has problems letting go when the organization gets bigger than the person can handle, since the talents required to startup an organization are different than those required to run a successful organization. The example he presents are a few organizations that have more than $100 million in revenues, and the founder is still an active developer and approves all changes to the code base. He states that most venture capitalists will recognize this, and will remove the founder from the organization, although Phillip does mention other solutions. This is similar to something I was told regarding an organization, where the new management inquired who were the people that the company could not survive without, and when they received this list, they proceeded to fire all those people. While it seemed as strange logic then, in retrospect, the company was able to succeed, partially because of this.

Another very interesting one was the one entitled the “Shoeless Children,” in which is based on the fable that the children of the shoemaker do not have shoes, since the shoemaker is too busy servicing his clients. The analogy is how some organizations are too busy creating new and better tools for their customers and use the latest technology for this, however, they do not create tools to help themselves and their own infrastructure is no where near their client's infrastructure. This is often based on penny-pinching, but its solution is not always as easy as expanding the budget, and Phillip provides a little more description in the article about the situations around it.

The final one is called “worshiping the Golden Calf,” and this is about hoping that a new technology or methodology will solve all the problems, but this new technology or methodology is poorly understood. This situation usually occurs where there is a poor shared vision or poor leadership. This “golden calf” could also be unknown, such as in the “hockey stick” revenue projection, where after a number of poor quarters, there are a few good quarters, and people start to believe that the ship is turning around and that it will continue in this pattern. Solving the pattern is not easy though.

I really enjoyed the article, and I look forward to seeing their book, as I am sure that it will open your eyes to situations which are around you. And knowing that there is a potential problem is the first step towards fixing it.

November 2, 2004

J#'s raison d'être...

Jim Fawcette has blogged a piece stating that Sun's law suit undermined Java, stating that the law suit against Microsoft discouraged Microsoft from using Java as its primary development language, but I do not buy this. With this logic, I can only guess that one of the UML vendors has also sued Microsoft, and this is what forced Microsoft to develop their new modeling language?

I am not arguing that the Sun law suit was a good thing for Java, but Microsoft has a long history of developing their own proprietary tools, and there are always reasons behind their decisions. Specifically, as noted by here, J# was late in the announcements, and I remember reading at one point that the reason for this was more that Microsoft was originally not going to provide a Java implementation, but later realized that Java was part of the U.S. college and university curricula as soon as late 1997, and by not providing a Java implementation, new developers would not be exposed to their technologies, and this is the reason that J# was added.

In the case of their proprietary modeling language, we received a demo of Visual Studio 2005 at OOPSLA during Richard Rashid's keynote entitled, “The Future Of Programming.” With such a title, I, along with many other attendees, were expecting more of a discussion in the more distant future than next year. Instead he discussed many of the technologies that Microsoft is presently developing and using in-house (such as PreFIX that should come with 2005) and some observations on the future (such as we are now almost at human-scale storage, where we are almost able to keep everything on a hard disk, without ever having to delete anything), but a good portion of this discussion was a demo of Visual Studio, including the model-zooming functionality. Following the keynote, I asked the demo's presenter two questions, first about cross platform tools and secondly about their choice against UML. Regarding the cross platform, he indicated very vaguely that there is something in the plan that he cannot comment right now (Maybe, or rather hopefully, something with Mono?), and regarding the UML question, his answer was simply that not everything is object-oriented. Regarding the latter comment, I find Keith Short's answer at least more in the proper direction, but I am not sure about the approach. I think I will just have to give it a run to see what they have really done.

Jim appears to make some other comments about what might have been, but without any references, it is hard to know whether these are opinions or what. I am not as certain as Jim is that things would be any different than they are now.

November 1, 2004

J2EE and .NET are friends after all...

Java Developers Journal has an article entitled “J2EE + .NET, in which suggests that a number of organizations are combining J2EE and .NET, taking the best of the two worlds into creating new applications. This is about taking a look at the proper tool for the job and selecting the tool based on all the factors, not just what you know.

While I agree with a good portion of the article, one thing that really sticks out of the article (and perhaps I am just reading into it) is that Microsoft has revolutionized development environments by allowing all developers to be highly productive in the environment, suggesting that the “type in which ever language you prefer” is an advantage. This is not to say that it does not have any advantages, but one major issue that is sometimes overlooked here is that of maintenance of the code. While yes, it is great for the new intern to be completely productive in a non-mainstream language, such as Eiffel ENViSioN, this environment is not a “read in which ever language you prefer” and since code is read more than it is written, the choice of language is still an important issue for maintenance, such as for resolving bugs or to extend the existing functionality.

The other issue is how some of the languages supported are more-or-less coerced onto the CLI framework. An example of this was when I was talking about the C++/CLI extensions, but an even better article on the topic is Richard Grimes article in the November 2004 issue of C++ Users Journal, where he describes extensions for properties, events (delegates), interfaces, generics, and more, and I find these extensions even more disturbing than I did before. Take for example the following sample class from Listing 2 of the article:

ref class Person {
public:
  property String^ Name
  {
      String ^ get() { return name; }
      void set(String^ b) { name = n; }
  }
  property int Age;
private:
  String^ name;
};

While these constructs are extremely powerful and all, this is not C++, and even with using the preprocessor, it looks like it would be difficult to make this portable in any sense of the word. In order for C++ to be a first-class citizen in CLI and to allow the other languages to work with these assemblies, such changes will need to be throughout the code-base, thus making projects less portable to other platforms, not to fail to mention some initial investment in exposing your API to non-C++ languages. Portability was obviously not one of their aims.

As a few groups that I was talking to at OOPSLA regarding the gcnew changes said, when in Rome, do as the Romans. If you were targeting a .NET application, why would you really want to use C++ in it? Yes, there are some things that C++ can presently do that C# and other languages are not as well suited to do or that you have an investment in current C++ libraries, but developing full applications in C++ would not seem to be a natural fit. This is a similar synopsis that JavaWorld gave to J# a while ago.

I realize that Microsoft is attempting to target C++ for Systems Development, but C++ is already a very confusing language, and adding more confusion to it is not necessary. The effort to migrate all Java applications onto .NET and vice versa was not always a good decision, and the first article mentioned discusses how we can actually bridge the two technologies together. Bridging C++ into the .NET world would have had a vastly different feel than the present Visual Studio 2005 line-up, and as strange as Managed C++ was, at least it was mostly standard C++.

October 31, 2004

The Shared User Vision...

One thing that have been discussing off and on has been Alan Cooper's “The Inmates are Running the Asylum.”  En route to OOPSLA, I decided to pickup this book again and I have finally finished reading it.  The last time I left it off was in Chapter 9, which was discussing the importance of user-centric design by use of personas and instead of thinking of software in terms of the features that it could provide, and that it was much more important to concentrate on the goals that the user had.  Accomplishing this requires some interaction design, which is what the next portion of the book deals with.

Alan states that the developers often confuse tasks with goals.  Tasks, he defines, are the steps that are done to accomplish goals, but unfortunately developers usually design user interfaces to complete tasks instead of accomplishing goals.  Take a step back from the context that Alan is talking about, one of my courses at OOPSLA has been with Kevlin Henney, and he reminds us that when developing object oriented software, the getters and setters are generally not the proper abstraction for an object.  More specifically, his example was for a Bank Account, where the methods provided are getBalance() and setBalance().  While this is a very powerful interface, this is not the proper abstraction to use, especially since in this case, the object could change state between the initial get and the final set.  As such, a better interface would be a method to acquire the current balance, a method to withdraw funds, and a method to deposit funds.  In addition to being a more coherent interface, the business logic can easily be applied in this design.

Likewise, the context that Alan is referring to is precisely the same issue, only it is a different user.  When designing user interfaces, the same comes out.  Instead of acquiring the information that the underlying algorithms require, consider the user's goals first, and these goals are not necessarily computer related.  Alan starts off the list of user goals, for example, by stating that one of the goals is to not feel stupid, for example.  One issue that Alan discusses when this happens, however, is that developers make up false goals for users, such as it is important to save memory, there must be a web interface, and more.  Perhaps they are requirements, but they are not goals.  Alan goes into great detail here, and even provides some information on making software polite.  Many of his ideas are great, but are not immediately obvious however.  It is not a notion of simply saying please and thank you, but rather becoming more human, as Clifford Nass and Byron Reeves' "The Media Equation".  In their research, they have discovered that humans interact with computers in ways similar to the ways that they interact with humans.  This means that when software indicates that they are doing something wrong, the interaction must be the same as when another person points out that they are doing something wrong.  In particular, you would not like someone to come over to you and tell you that the work that you have been doing is completely wrong, yet repeatedly in software, this happens.  For example, people will select options that appear to be usable in the current function and the software will come out with a phrase that would definitely not be appropriate when coming from a human.

In the next chapter, Alan discusses usage scenarios, which are essentially use-cases.  The important thing is with scenarios is that most of the time, the users will only use a finite set of functionality, as the 80-20 rule would suggest.  Although this subset could change overtime and depending on the task, these tasks should be easily accessible to users.  The problem is probably determining proper use-cases and which functions are in that finite set.  To help in this regard, Alan provides his table of Perpetual Intermediates, which describes the number of users that are beginners, intermediates, and experts, and most users are intermediates.  The users will evolve from beginner to intermediates quite fast, however, most users will stop here, and only a few will progress to experts.  The situation is, however, that experts can get bored of the software, and could migrate to other software, so targeting these users is not ideal.  Your goal should be to optimize your software for your intermediate-level users, and make it easy for beginners to learn.  One major component of this, however, is the use of vocabulary, where the vocabulary should be consistent between the developers and interfaces and the definition should be shared. 

Software companies have repeatedly continued shipping software that does not meet user expectations, but this is not for a lack of trying. The example that Alan provides is that of Microsoft Windows, where up until Windows 3.0, people really laughed at the usability of Windows. Alan argues that this situation exists because software vendors are more interested in shipping regular releases of software rather than focusing on usability and stability. Each release, they ship a version of software, and based on user reactions, future versions of the software address those complaints, and this is an acceptable practice in software, and many software companies attempt to emulate our friends at Microsoft.

But why? According to one of the case studies that Alan provides in the book, the proper interaction design of the Logitech Peacock met user's needs so well that it resulted in fewer support calls than any of its other products. Support and maintenance of the software being more expensive than properly designing the software from the start, it just seems completely backwards to continue developing software in this fashion.

Another aspect that I totally agree with Alan about is the fact that some interfaces are developed without showing them to users first.  In many organizations, software is developed and by the time users really get a feel for the software, the development is almost completed.  The analogy that Alan uses that is fantastic is that a piece of sand paper can make a chair or a table smoother, but the sand paper cannot turn a table into a chair or a table.  This is a great analogy because if you have created the wrong interface to the application, the code that you had will probably need to be rewritten entirely and cannot just be adjusted directly as well as we would like, but this is unlikely to occur at the end of a development cycle.  The only way to develop for this case is to prototype and let user's experiment with the software well before it is fully developed, where the code is easily formed into another object.  One analogy that I like is that of pottery, where when you are creating a vase, the clay can be easily maneuvered into a shape and form, however, once it is baked in the kiln, there is no way to change its form without breaking it.

Innovation is another topic that is discussed throughout the remaining chapters of the software. I never thought of it in this fashion, but the style guidelines provided by Apple and Microsoft for their respective operating systems stifles the true innovation of interaction design, especially since these style-guidelines are not done by a third party. In other words, this would be like dictating that all of Microsoft's competition work in visually compatible fashions to this document, and those that do not, are not compliant. The ability to innovate and to make new controls and to think of software from a new perspective is blocked by the need to be comformant.

On the same token, Alan points out that many companies that are on a regular release cycle, such as a software version per year, are likewise stifling innovation. The need to deliver software in a finite fixed time forces the time to do the proper analysis of what users require and proper interaction analysis to in a short time. While I agree with Alan on this front, there are some organizations that have addressed this by having concurrent development of software versions. Doing this is difficult to manage, however, it does provide for more time to do upfront design. But there is definitely a need for this regular release cycle; companies that do not release regular software versions appear to be idle. For example, when I was in the market for a design tool, one of the tools that I was considering's product name ended with 2000, and the last press release of this company was in 2002; being 2004, it seemed to me that this organization was idle. When I contacted them regarding this issue, they said that they have released some products in between, but have not really changed the version number; even with this answer, I did not feel comfortable investing in this product.

I regularly have to perform interviews for interns at my current organization, and during these interviews, one of my all-time favourite questions to ask is, "if I were to give you a project to develop from scratch, which programming language would you use?"  This is one of my favourite questions because I have yet to have any applicant answer it correctly.  There is absolutely no one that has to date asked me what the project is, and based on this, they generally answer the question based on the language that they are most comfortable in or the language that they want to learn the most.  My desired answer is one that takes into consideration the strengths of the language to solve the problem.  There are definitely some tasks that a scripting language is more well suited for than a compiled language like C++.  These developers are focused on solving a problem without knowing what the problem is.  But this issue is more fine grain than interns.  I have also experienced similar situations with managers and experienced developers, who ask prematurely whether the interface will be a rich-text interface or a web interface, or whether it will be in C++ or Java, and many people simply do not understand that to answer these questions, there is very little opinion in it.  The decision to prefer one technology over any other should definitely be the technology that solves the majority of the user's issues and meets the user's goals.  Likewise, one thing that is mentioned in the book that I agree with is that user interfaces do not necessarily imply a graphical user interface.  All too frequently, we begin developing graphical user interfaces out of habit or thinking that this is what users need, however, there are times where the use of text interfaces is appropriate, and one of the examples that Alan provides for this is a point of sale application; in the minds of many people, it would seem that this application would imply a graphical user interface, but a text interface was created on one project, and it was quite easy to use.

Part of the problem that I see here is that applications unfortunately suffer from an identify crisis, and the sad part of this is that there are too many such applications on the market right now.  The identify crisis goes way beyond the screen full of buttons, but also in the ways that these products are created.  In one of the previous chapters, a great example of this is the executive who prefers the navigation via the mouse, and therefore, this becomes a requirement, whereas the application may be better suited for the industry by use of the keyboard.  All of these crazy visions of the user are resolved by using personaes, because the right application will be created and the question of whether t should be a graphical user interface or a textual user interface, a keyboard-driven or mouse-driven interface, and the multitude of other options are not decisions that come from the developers, marketing, executives, etc., these are decided upon by the needs of the person who will actually use the application, and so stated, probably the one that influences purchasing of it at some level or another.

Alan discusses upfront design in the context of interaction design, and states that once the interaction design is completed and documented, it can be easily implemented by developers. He states that most of the time (probably 80%) should be spent on interaction design and the remaining time is spent on the implementation. But the interaction design, by definition, only narrows the scope into what features are delivered and how these features work. The entire topic of software architecture is not discussed, but this is equally important to successful and maintainable software.  I am not sure if Alan has put this in with the implementation.  Either way, he does clearly state that this interaction design must be documented and presented to everyone involved to acquire the shared vision of the software products, arguing that the shared vision is required to avoid people doing tasks that are unrelated to the end goal of the product.

Alan argues that doing the design prior to the implementation is something that is fairly new to software development.  In some environments this can be true.  His analogy for this is rather interesting, in that he picks the creation of a modern movie, which proceeds in three stages: pre-production, production, and post-production.  As bizarre as this may seem, it actually dovetails quite nicely with modern software development.  During the pre-production stage, the script is written, production of the film is designed, actors are casted, and money is raised.  During production, the movie is filmed per the plan in the pre-production.  During the post-production, the film is edited, visual effects are added, and marketing starts.  The first aspect to note is that there are many people involved in creating movies, so any thing that is changed in one of the later stages becomes harder and harder to change and the cost of change is prohibitedly expensive, and people know this in the movie industry, so they attempt to do everything in the earliest stages possible, and avoid changes that should have been done in previous stages.

Software development essentially has the same stages, although there names are different, but many organizations are not as organized as the film industry in not going back to earlier stages, or even observing that there are stages.  Books like Software Engineering by Robert Pressmen discuss these software stages, but the reality is that many organizations do not observe them fully, and we do not have a clear, shared vision of what is being created.  Design is intended to describe this shared vision so that people can understand what is happening.  Developers understand what they must create and marketing understands what the developers will deliver.  This is not a situation where the developers believe that they are delivering one product and the marketing department believes they are delivering another, and the customer has another vision.  In reality, there should only be a single vision, and that should be the customers visions, as denoted by the personae for the application; it does not really matter what the other people want in the software and what they think the software should do, in reality it is the customer that will use the software, and all their needs must be met.

Another aspect that he states is new is performing usability testing prior to the product being created.  At present, most software development goes to both software testing and usability testing only after the software is in a completed (at least partially) state.  Similar to security, software usability cannot be an after thought.  It must be designed from the start; attempts to resolve user interaction issues after the core application is developed will be more expensive and difficult to do than if done prior.  This is similar to the aforementioned analogy of the creation of a movie; it is easy to change the object that explodes in the pre-production scene, but after this point, it can be very difficult and expensive.  Such kinks should be ironed out prior to the software being built; this is generally done via prototypes.  This tool makes sure that there is a shared vision and that users understand what is being created.  This is not to say that prototypes are not created today, but rather, users are not always involved with them.  In may cases, the prototype is created as part of the estimation process or as a validation that the product can actually be created, but in many cases, such interfaces are not shown to the actual users of the application.

I say these items in rather broad, all inclusive terms similar to the way that they are presented in the book.  In reality, not all software is created this way, but in my experience, there are still many that proceed in this fashion.  New methodologies such as extreme programming involve the user in the building of the application and the proponents of short-iteration iterative development, but this is unfortunately such practices are not the norm.  I clearly see this as an aspect of our development paradigm that needs to change.  As denoted in Steve McConnel's keynote in OOPSLA, our software is a little too complex at this state to do the entire design at the beginning, but we still need to understand what the software does in simple terms and what we are actually delivering.  This shared vision of the software must still hold.

And this is really what the Inmates Are Running The Asylum is all about.  To create software that meets our customers needs, we need to know that customer and we have to design the software for that customer.  The book highlights the reasons that there is a problem right now, and presents some ideas to changing the present situation.  I recommend this book (or its companion, About Face 2.0: The Essentials of Interaction Design) to every developer.

October 28, 2004

Extending C++ and Java...

For the past week, I have been at OOPSLA, and I have been rather busy collecting all kinds of information that I will eventually talk about here, but I thought that I would start slowly discussing the conference.

Herb Sutter presented yesterday a talk entitled, “Concrete Languages on Virtual Platforms,” and the talk was slightly differently than what I had in mind. What I had imagined was more of a discussion of why we use virtual platforms and targeting language features on the platform, but alas the discussion was about the coercion of C++ onto the .NET platform for Version 2.0.

As you are aware, C++ has, for the sake of simplification, two types of variable allocation methods, viz. stack variables and heap-allocated variables. Stack variables are constructed when introduced, and are destroyed at the end of the scope of where they are introduced, whereas heap-allocated variables are constructed by calling new and are destroyed by calling delete.

The situation is, however, that the CLI platform uses garbage collection. Porting C++ onto the CLI means introducing garbage collection into the language. Stroustrup has always said that garbage collection would be added to the language, however, the approach that was chosen is not standard, and will result in code specific to the .NET platform, such as follows:

MyClass ^t = gcnew MyClass()

As you see, there is a new keyword, gcnew, and this is assigned to a garbage collected pointer, denoted by the caret (^, or the hat), and following this, you can use the pointer as a standard pointer. The other change is with the destructor of the class, whereby the finalizer method is now !MyClass(). You can read this for yourself over at MSDN. Herb does, however, point out that this is a standard language extension, but I agree with Kevlin Henney that this is like saying that C++ is a standard language extension of C.

In addition to bringing up some bad memories from Pascal, I am not convinced that this is the best way to implement garbage collection within the C++ language, but this is not what I really wanted to talk about today, so I will leave this topic for another day. But while discussing all of this, one of the topics that Herb focused on is, what he finds, the horrors of finalization. In Herb's mind, we need to distinguish between object destruction and freeing memory, and garbage collection is only focused on the latter, but today, this is not really true. As an example, in your finalizer, an object could be resurrected by simply assigning the this pointer into a static variable. As another example, per se that you have a set of objects that depend on each other in a circular fashion. In this case, the garbage collector must then choose one of those objects to destroy first. This means that when the object calls the finalizer, it cannot access other objects, as these objects may have been destroyed prior to this finalizer. Because of these reasons (and more), Herb insists that garbage collected languages separate the concept of object destruction and freeing memory.

The only facility, however, where I feel that this makes a difference is with patterns, such as the Scope Locking Pattern [POSA2] and other scope-related patterns, which are important in languages like C++. As an illustrative example, the following code acquires a lock and then calls doSomeOperation():

void MyClass::myFunction()
{
  LockGuard lock( objectLock );
  doSomeOperation();
}

In the above pattern, the lock constructor acquires a lock, and the destructor releases the lock, and this is a very safe way of implementing multithreaded applications, but in languages like Java and C#, the above Pattern is not utilized, because there are no destructors, and, if they run at all, finalizers may be ran much later than you expect.

For the sake of argument, let us ignore the fact that Java has the synchronize keyword (which actually Herb's presentation did) and imagine that we are using a set of classes, similar to those discussed here. Now our implementation in Java becomes a little heavier than the above C++ implementation:

void javaMethod() {
  LockGuard lock = new LockGuard( objectLock );
  try {
      doSomeOperation();
  } finally {
      lock.release();
  }
}

When there is more code, the more chance that developers will get it wrong (an another argument against the gcnew and ^). In so saying, Herb also points out that the C# fashion of accomplishing this is via:

void csharpMethod() {
  using ( new LockGuard( objectLock ) ) {
    doSomeOperation();
  }
}

In such a comparison, this looks horrible for Java. In fact, in my first exposure to C#, I mentioned the fact that I really liked the using keyword, and as such, I hoped that this would eventually be brought over the Java.

One very interesting part of attending OOPSLA is that there are many big names in the software industry. In fact, sitting right beside me during the above discussion was Joshua Bloch. Earlier today Joshua was signing copies of his Effective Java book, and having read this book in my early Java days, I approached him and asked him about the types of things that he would change in the book. It turns out that he is presently writing a book on Java Puzzles (I presume something like Herb's Exceptional C++ series) and after this, he will be updating this book, and to remain on topic for once, I will just say that there are some very interesting additions to this book coming soon.

Following the book discussion, I asked Joshua about what he thought about adding the using keyword to Java, and it turns out that he was presenting some ideas at The Java Platform: Tiger and Beyond workshop, and essentially what he says is that the using keyword only does something when exiting the scope, and does not do something when entering the scope. In addition to not adding a new keyword to the Java language, his idea is to essentially introduce a new interface which we will call, for lack of a better name, Doable, which is defined as follows:

public interface Doable {
  void begin();
  void end();
}

From this interface, the idea is that the developer would use it via the following:

do ( new MyDoableClass() ) {
  doSomething();
}

And underneath the hood, some equivalent structure as the original Java implementation above would be created and that would call the interface methods also. This is a very exciting idea, but now that I think about it, I think that perhaps the begin() method would be rarely used. Specifically, if you consider the above implementation, I am constructing a new concrete interface, therefore most of what could be placed in the begin() method would usually be placed in the constructor. This is not to say that you will never have a class passed in that will already exist that may benefit from this begin() method, but I would imagine that this would not be the norm, and in the rare case that a method like begin() would be required, the method could be explicitly called prior to the doSomething() from above. More specifically, I see the more popular uses of this construct being more localized references, such as manipulation of I/O, Sockets, SQL, etc., which currently require a close() method to be called in a finally section. I cannot think of any case where the begin() would be useful off the top of my head, but I am sure there are some cases; I just am not sure how necessary this is.

Nevertheless, I look forward to seeing something like the above implemented in a future Java version, in addition to some of the other proposals that I have heard, including switch statements on Class and Strings and adding a const-like feature to Java, such as is implemented in javari, of which I may describe at a later time.

Earlier Entries

<  1  2  3  4  5  6  7  8  9  10  11  >

Navigation

Recent Posts

eyt*