Find your next scenic drive!

October 9, 2004

The survey says Java Generics helps Code Maintainability...

In Java Generics: Better Code or Worse?, I mentioned that I feel that Java Generics will help code maintainability, and according to Java Specialists' Issue 96, three-quarters of the respondents agree with me, but are as inexperienced as I am with Tiger, so this opinion could change overtime, but I really doubt it.

The real point of Issue 96, however, is not to discuss this. I was actually hoping to see some key points of why people are for it and why people are against Java generics, as I think that this would be interesting. Instead, the discussion in this newsletter is about how a variable declared final is not necessarily constant under J2SE 1.5, whilst it was under 1.4.2. Of course, this is not from a direct-use point of view, as I was initially under the impression of, but rather via reflection on certain types. Heinz provides a full historical viewpoint on this, and why these rules are different under 1.5. While reflection is not something I personally use regularly, it does provide some good insight to the Java language.

October 4, 2004

The Pattern-Based Future...

InformationWeek has an article about Grady Booch about the future of software, and it appears that Grady thinks that the future is in Patterns, described as “algorithms that pull together objects.”

As a recap, the Software Patterns Movement started when Design Patterns: Elements of Reusable Object-Oriented Software (affectionately referred to as the GOF book) was published in 1994, and was greatly inspired by the works of Christopher Alexander, such as in The Timeless Ways of Building where Christopher's premise is that by observing and communicating architectural patterns, buildings could be made to perfection by simply assembling compatible patterns. Interestingly enough in Christopher's book, he states that all patterns should be written down, and in another round of the survival of the fittest, only the most fit patterns will spread.

In the software world, when the GOF book was published, an entire myriad of software patterns books were published. These software patterns vary in quality, but there are a lot of design patterns. It has become so uncomfortable to track down software patterns that books like The Pattern Almanac 2000, not to fail to mention a few attempts at publishing such information on-line, help organize them.

The article that started out this entire babbling kind of makes it seem like software patterns are new, but they are not as I have highlighted above. This being said, I still think that software patterns are important and are very much a part of the future. There is a lot to be learned from software patterns. As just a simple example of this, I have recently discussed the scope of class data members as being something fairly new to place data members as private instead of protected, however, if you look at the source within the Design Patterns: Elements of Reusable Object-Oriented Software book, many examples use this technique.

Learning algorithms and patterns is a way to leverage knowledge from before. There are very few problems that we solve that, as much as we would hate to admit, are truly unique. Generally the way that we build software today is by building components and modules and they are combined in ways that make our global application more or less unique, but many of the components created and the interaction between the components are not unique. Software patterns, like algorithms, present us with a catalog, where we can browse through the catalog in order to select patterns that meet the criteria that we are attempting to obtain from the software. In addition to this, it provides a language to communicate with other engineers; without the QuickSort algorithm, how would you describe the QuickSort algorithm? Just the QuickSort name provides a mental pictures in engineers that you do not need to describe the internal workings, such as the partitioning mechanisms, in detail.

Patterns offer the same communication advantage, however, the GOF book has introduced a form that patterns are in that can make patterns better. When dealing with books on algorithms, the algorithms generally only present the algorithm and may describe some areas where the algorithm will perform well and where it will not perform, but the form that algorithms are presented varies greatly from book to book. With software patterns, the GOF book has proposed a form that most software design pattern book follow. This form allows you to quickly look at the description and know what it does, why you may want to use it, how it works, and some consequences of using the pattern. This description provides you sufficient information to decide whether the pattern is applicable to what you are trying to do.

As Christopher Alexander mentions in The Timeless Way of Building, some patterns will eventually become part of your language, whereas others will not. Part of this is applicability, but part of this is also exposure, as Christopher mentions that the initial subset of a language that child learns is based on the set of words that the child is exposed to. As the person is exposed to more and more vocabulary, the person can make the vocabulary part of their language, or the person will simply know what the word means. And this becomes the language that you hear when communicating with them, similar to the words that I use on this blog are in the subset of my language.

The movement from algorithms to design patterns is a natural progression, as I mentioned in Knowing The Language. When we used to develop code line-by-line, it was easier for us to think at the algorithms level, however, with objects and components, it becomes more important to think at a higher level, and to describe the interaction of objects and components. This is where design patterns are incredibly useful, and I agree with Grady that this is not going to change in the immediate future.

Longhorn is a Big CLR Interpreter?

ACM Queue is running an article entitled Longhorn Ties Platform Apps to Core Operating System, which provides a rather fast overview of the Longhorn deliverables, all placed into a table. Of course, this is mostly old news. The only twist that is either new or I did not realize is that Longhorn is now going to be just a huge CLR interpreter, which will protect users from hardware and architecture implementation details, effectively giving each application a sandbox to work in by itself, similar to Java. The only true difference from Java is the fact that CLR is not part of the core operating system, similar to how Mozilla is not part of the core operating system but Internet Explorer is. I suppose that all the security patches in the past bit have not yet sunk in to keep things out of the core operating system...

October 3, 2004

Core Servlets and JavaServer Pages...

A bit ago, I downloaded the first edition of Core Servlets and JavaServer Pages from Javalobby, but electronic books of this length are harder to manipulate than a book, and so I have recently purchased Core Servlets and JavaServer Pages, Volume 1: Core Technologies, Second edition, and over all, I find it a good book. Of course, it should be noted that servlets and web development are not new to me, and as such, I skimmed through large portions of the book.

One of the key things that I enjoyed in this book is the fact that it teaches architecture and design of servlets. Instead of being strictly a HOWTO book, which illustrates samples left and right of how to do something, this book discusses some design issues to consider. For example, they do a good job at comparing Servlets to JSP. In this discussion, he shows how to do some advanced things like why you may want to consider using the MVC Pattern and how this would work with minimal effort. The only part that was lacking, in my opinion, were UML diagrams to show the structure of the classes involved in the MVC.

As another example, they describe cookies at length, discussing some of the pitfalls and some of the advantages, and then compares them with Sessions, which he also provides the same indepth discussion of how to use them, and how to avoid common pitfalls. A similar discussion occurs in the JSP section where they describe the applets; while they make it perfectly clear that applets may not be the best way to go, they go straight in to discuss all the common problems associated with applets, and how to get around them or to work with them.

In addition to focusing on Servlets and JSP, the book also points out some insights into Java. Although a lot of its content I was already very familiar with, I think that it would be a good book for someone who is new to Java. As an example of this, there are chapters that are dedicated to JDBC, and although it does not go deep into the topic, it does provide some good insight to make your queries faster.

Furthermore, the book also provides a good introduction to HTTP, forms, and other web-related technologies.

My only complaint in the entire book its HTML and CSS. The tags are all in caps and the documents are not well formed, making the transition to XHTML more difficult, not to mention harder to read. Regarding CSS, there are a very few references to it, and there is no entry in the index regarding CSS (the acronym or the full content).

Do not get me wrong; I am not saying that it should have a lot of content on CSS, and in fact its omission shows that developers should not be designing the look and feel of a site exclusively. But even with this rational, it would have been a good addition to simple discuss why developers should bother using CSS. Specifically, by defining the right classes, the designer can easily augment a predefined page without asking for code changes by simply changing the CSS file.

Volume II is not yet available, however, I am looking forward to taking a look at it, as it does cover more advanced topics than this particular book, such as JSTL, Apache Struts, JSF, JAXB, advanced JDBC and more.

Another book that has been recently released is Effective Enterprise Java by Ted Neward. This book is in Scott Meyers' Effective Software Development Series. I have only flipped through it so far, but its content looks interesting.

October 2, 2004

Java Generics: Better Code or Worse?

In the latest Java Specialists newsletter, it seems that some people were not comfortable with Generics, so much so that Heinz sent a follow-up, imploring us to send e-mails justifying our position on generics. In addition to sending this to the proper list (people who know me well already know which one), I decided to also say something here.

Prior to getting too involved in this discussion, however, it is important to realize that I have only started playing with Tiger when it was released on Thursday, and with this in mind, my comments are coming mainly from what I have read about Java's generics and what I know about C++'s templates. But really, the answer to this question is not about the language that is being used; it is about the techniques associated with generic programming.

With this in mind, my position is that Generics can make software easier to maintain. Recently, some Java Journalist commented on how the culture in Java would not generally be impressed by a developer who wrote their own container class; a normal reaction to this case would be to reuse one of the containers in the java.util package. In Java, we are more likely to reuse these classes; in other languages like C, where container implementations are not part of the standard library, developers must implement their own containers for each type, and the way that this is generally implemented is in one of two ways:

  • Copy and paste an existing implementation.
  • Roll your own.

While both points have their advantages, such as they can be optimized for your particular environment instead of being a general-purpose container, but both approaches have a similar disadvantage. In the former case, the copy and paste case, it is very likely that you are acquiring a perfectly working piece of code, but it is also possible that the code that you will be primarily using is not presently used, and therefore has bugs. On the same token, as software maintenance goes, the two pieces of code mature differently, such as a developer will modifying one, and forget to the other one. Over all, this is good recipe for disaster. In the latter case, you are reinventing the wheel. While yes, it is cool to show everyone that you still remember your High School lessons of how to write containers, this new implementation will need to be tested, and is is very likely that there will be a few bugs in the new wheel.

In C, a workaround to this situation is to use create container methods for a void* pointer, which basically permits the container to contain any type of data. In essence, this is similar to the java.lang.Object (only void* far worst, lacking, amongst other things, a ClassCastException). Up until J2SE 5.0, we had no alternative than to use a container of raw pointers. On one hand, this ability was good for those rare cases where you have a heterogeneous set of data, but in most cases, you have homogeneous types of data, or at least a common base class or interface that can be used, and constantly casting everything was error prone, in the sense that if you originally wrote a class to have a container of String, and later decided that it would be better to have a StringBuffer, depending on how your code was factored, it could still be possible that a String object either be inserted, removed, or accessed in the container. The only way to find out is to compile, test it, and see if you have any ClassCastException. And if that happens to work, I would just double check your test program to make sure that all the branches are tested in it.

This is one of the areas where generics come into play. In the previous example, if the user had created a LinkedList<String>. and then changed it to a LinkedList<StringBuffer>, then the compiler can catch any improper references that go into the linked list.

One of the other areas that C++ uses generic programming is with algorithms. Consider for a moment the std::distance method, which looks like:

template<class InputInterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator second)

The above function (the implementation is left as an exercise) essentially takes two iterators and calculates the distance between them, returning the type associated with the container for the length parameter. The class is generic because any class that implements the interface of an InputIterator can execute this method. Now, the attentive reader will note that I just said the word interface; in C++, there is presently no interface support, and therefore, this above mechanism allows C++ the ability to fake interfaces, albeit harsh, in the sense that the exact interface is only supported via template instantiation or documentation (if any exists). The solution in Java would be simple, and it would not require any generics; it would simply require a class that abides to the InputIterator interface.

On the other hand, however, C++'s template specialization allows the for special interpretations of the iterators depending on the exact type of iterator. For example, in the case of a linked list, if you have a pointer at the beginning and one to the end of a sequence, the only way to discover the distance between them is to forward one iterator until they meet. However, in the case of a Vector in C++, where the elements are contiguous, you could subtract the value of the pointer at the end by the value of the pointer at the beginning. While the former approach does work on Vectors also, the latter implementation takes advantage of the underlying implementation, and optimizes this method. This genre of optimization, however, could not be done presently in Java (unless you used a instanceof hack), but this may eventually work. Furthermore, C++ allows the redefinition of types via the typedef keyword, as demonstrated above with the typename iterator_traits<InputIterator>::difference_type; this would allow containers to extensible in number; in other words, if an int were assumed, this would limit the container to having 231-1 entries, however, in C++, this number is defined by the container, and therefore, could be a long, float, or any other value at that.

Just going through some C++-based algorithms that are implemented via generics, I cannot seem to think of any algorithms that could not be rewritten without some proper abstraction of interfaces (perhaps some some generics in them) or members of a class, but I am still convinced that there are generic algorithms that would definitely benefit from Java's generics.

The new syntax of generics is definitely odd to Java developers, and to be honest, many C++ developers are uncomfortable with the syntax. As with any technique, generics could be over used, as mentioned here before. When designing coding, it is important to think about if it is a benefit for a language feature to be used. In my opinion, for C++, generic programming serves no purpose unless you have at least two truly different types using the generic service. With this in mind, if you are writing a class, such as a pool of database connections, then it is probably not a good idea to make the interface to the class generic, however, the internal workings would benefit from the type safety associated with homogeneous, checked containers, and as such, I would recommend it within.

In summary, since many containers of objects are homogeneous, Java's generic support allows this to be enforced by the language. Although interfaces can be used to replace some of the needs for generics, there are algorithms that exist that will truly benefit from the generic support. Between the code reuse and the type safety, I am sure that generics will render code easier to maintain.