Code

Out of Tune with Anti-Patterns?

Not knowing how to spot an anti-pattern is just as important as spotting a defined pattern.

An Anti-Pattern is a pattern that reveals a problem implemented with a bad solution.

Identifying bad practices can be as valuable as identifying good practices.

A good Anti-Pattern also tells you why the bad solution looks attractive (e.g. it actually works in some narrow context), why it turns out to be bad, and what positive patterns are applicable in its stead.

An anti-pattern is something that looks like a good idea, but backfires badly when applied.

It’s not fun documenting the things that most people agree won’t work, but it’s necessary because many people may not recognize the Anti-Pattern.

In the old days, we used to just call these ‘bad ideas’. The new name is much more diplomatic.

While it is reasonable to assume that the principal reason people write software is to provide solutions to specific problems, it is also arguable that these solutions frequently leave us worse off than before we started. In fact, academic researchers and practitioners have developed thousands of innovative approaches to building software: from exciting new technologies to progressive processes, but with all these great ideas, the likelihood of success for practicing managers and developers is grim.

Booker Showers

Cloneable Interface Design

A cloneable interface design often requires a clear separation between a type and its implementation. Often it is unavoidable to provide a public clone() operation for such a type when the type is used as part of the state of an object.  A cloneable interface design relies on the following factors:

Cloneable Interface Design Forces and Facts

  1. Accessor methods in Java should return a copy of internal state variables instead of references to the internal variables – in order to maintain an object’s integrity
  2. When values given to constructors are to become part of the state of an Object and should be copied instead of just referenced.
  3. There are no constructors available in an interface declaration, so a “copy constructor” cannot be declared.
  4. The visibility of a clone() method needs to be public to allow arbitrary client classes to clone the object

Example of Problem:

public interface State {
//
// some operations
//
}

public class C { public C (State s) { 
state = new State(s); 
state = s; 
}

public State getState() { 
return state; 
}

protected State state; 
}

Solution:

public interface State extends java.lang.Cloneable {
        //
        // some operations
        //
public Object clone();
}

public class C { public C(State s) { 
state = (State)s.clone(); 
}

public State getState() { 
return (State)state.clone(); 
}

protected State state; 
}

Booker Showers
Rhythm Section

The Rhythm Section (Frameworks)

 

Intention

Getting applications up and running in the shortest amount of time is critical these days.  This involved reducing the learning curve and implementing many concrete and final classes.  The following paragraphs examine the importance of framework design.

Frameworks

Frameworks reuse both design and code. Aspects of a design, such as the kinds of objects, are easily described by code. Other aspects are not described well by code, such as invariants maintained by objects in an ensemble. The fact that aspects of a framework are not expressed well as code makes frameworks harder to understand than abstract classes. A design must emphasize its details of a at the expense of others. A framework concentrates on describing object that make up the program and how they interact.

Dataflow is de-emphasized, but the communication between object is emphasized. Since frameworks provide abstract algorithms, users of a framework usually ignore the details of these algorithms and concentrate on designing and combining objects. The concept of a framework is harder to understand than that of an abstract class. Abstract classes can be defined either by how to recognize them or how to use them. Unfortunately, there is no simple way to tell whether a set of classes is a framework, so frameworks tend to be defined on how they are used.

The important classes in a framework, such as of Model/View/Controller, are usually abstract. Like Model/View/Controller, a framework usually comes with certain concrete subclasses of the classes in the framework. No component library is perfect to derive new concrete subclasses of the abstract classes in the framework. A good component library is valuable in addition to the framework, the essence of a framework is not the component library, but the model of interaction and control flow among the objects.

Frameworks are informally defined early as a set of objects and how they interact. Most the object ­oriented frameworks are specified by informal documentation and a set of (usually) abstract classes that represent the objects. The classes give the operational specification of how objects in the framework work together.

Given a specification language for describing the behavior of a set of objects, a framework would be a function from the set to constrain the behavior. For example, the Model/View/Controller framework would be a function from the three objects in a MVC trio: the view has a function from the state of the model to an image to invariants like the image on the screen inside a view’s bounding box is its function applied to the state of the model, and to operation sequences like whenever the controller changes the state of the model, it performs the operation on the view, which will redraw the screen. Note that a framework can define both the invariant and the outline of the algorithm.

Frameworks rely on undefined properties of the objects, such as the function from the state of the model to the image. A framework is filled out by selecting objects according to how they define these properties. The objects in a framework often place additional constraints on each other. Views (controllers) often use specialized operations to read (change) the state of a model. The major problem with expressing frameworks in a programming language is that it is hard to learn the constraints that the framework imposes on a program. The major advantage of expressing a framework as a program is that the algorithms and data structure of the program are automatically reused by every instantiation of the framework. There is usually an abstract class for each component in the framework. The algorithms and data structures that are reused are usually defined by these abstract classes. Each subclass of the abstract class defines a kind of component that fits into the framework, and they inherit much of their implementation from their abstract superclasses. This makes it easier to develop a library of components that can be mixed and matched within a framework.

A framework would be described both operationally and in terms of the constraints that it places on its components. This would not only provide code reuse, but make it easier to learn how objects in the framework interact. A framework reuses analysis, design, and code. It reuses analysis because it describes the kinds of objects that are important and how a large problem should be broken down into smaller problems. It reuses design because it contains abstract algorithms and describes the component interfaces that the programmer must implement and the constraints that any implementation must satisfy. It reuses code because it makes it easy to develop a library of compatible components and because the implementation of a new component can inherit most of its implementation from an abstract superclass. All of these are important, though in the long run it is probably the analysis and design reuse that provide the biggest payoff.

A framework hides the parts of the design that are common to all instances, and makes explicit the pieces that need to be customized.

A framework is most valuable when the part of the design that is hidden is the part that programmers find hardest to understand.

A class that is not abstract is concrete. In general, it is better to inherit from an abstract class than from a concrete class. A concrete class must provide a definition for its data representation, and some subclasses will need a different representation. Since an abstract class does not have to provide a data representation, future subclasses can use any representation without fear of conflicting with the one that they inherited. Creating new abstract classes is very important, but is not easy. It is always easier to reuse a nicely packaged abstraction than to invent it.

A programmer usually tries to create a new class by making it a subclass of existing class, since this is less work than creating a class from scratch. This can result in a class hierarchy whose top­most class is concrete. The top of a large class hierarchy should almost always be an abstract class. As a programmer gains experience, they will then try to reorganize the class hierarchy and find the abstract class hidden in a concrete class. The result will be a new abstract class that can be reused many times in the future.

An example of a class that needs to be reorganized is View, which defines a user interface object that controls a region of the screen. A view might have many subclasses, but is concrete. A careful examination will reveal a number of assumptions made in a view that most of its subclasses do not use. The most important is that each view will have subviews. In fact, most subclasses of a view implement views that can never have subviews. Quite a bit of code in a view deals with adding and positioning subviews, making it very difficult for a beginning programmer to understand the key abstractions that a view represents. The solution is simple: split View into two classes, one (view) of which is the abstract superclass and the other (view WithSubview) of which is a concrete subclass that implements the ability to have subviews. The result is much easier to understand and to reuse.

http://wp.me/p2MYVz-3m

Booker Showers

Architectural Musical Chairs – A Software Design Parody

Software Design Parody

Dear Mr. Architect:

Please design and build a house for me. I am not quite sure of what I need, so you should use your discretion.

My house should have between two and forty-five bedrooms. Just make sure the plans are such that the bedrooms can be easily added or deleted. When you bring the blueprints to me, I will make the final decision of what I want. Also, bring me the cost breakdown for each configuration so that I can arbitrarily pick one.

Keep in mind that the house I ultimately choose must cost less than the one I am currently living in. Make sure, however, that you correct all the deficiencies that exist in my current house (the floor of my kitchen vibrates when I walk across it, and the walls don’t have nearly enough insulation).

As you design, also keep in mind that I want to keep yearly maintenance costs as low as possible. This should mean the incorporation of extra-cost features like aluminum, vinyl, or composite siding. (If you choose not to specify aluminum, be prepared to explain your decision in detail.)

Please take care that modern design practices and the latest materials are used in construction of the house, as I want it to be a showplace for the most up-to-date ideas and methods. Be alerted, however, that the kitchen should be designed to accommodate, among other things, my 1952 Gibson refrigerator.

To insure that you are building the correct house for our entire family, make certain that you contact each of our children, and also our in-laws. My mother-in-law will have very strong feelings about how the house should be designed, since she visits us at least once a year. Make sure that you weigh all of these options carefully and come to the right decision. I, however, retain the right to overrule any choices that you make.

Please don’t bother me with small details right now. Your job is to develop the overall plans for the house: get the big picture. At this time, for example, it is not appropriate to be choosing the color of the carpet.

However, keep in mind that my wife likes blue. Also, do not worry at this time about acquiring the resources to build the house itself. Your first priority is to develop detailed plans and specifications. Once I approve these plans, however, I would expect the house to be under roof within 48 hours.

While you are designing this house specifically for me, keep in mind that sooner or later I will have to sell it to someone else. It therefore should appeal to a wide variety of potential buyers. Please make sure before you finalize the plans that there is a consensus of the population in my area that they like the features in this house.

I advise you to run up and look at my neighbor’s house he constructed last year. We like it a great deal. It has many features that we would also like in our new home, particularly the 75-foot swimming pool. With careful engineering, I believe that you can design this into our new house without impacting the final cost.

Please prepare a complete set of blueprints. It is not necessary at this time to do the real design, since they will be used only for construction bids. Be advised, however, that you will be held accountable for any increase of construction costs as a result of later design changes.

You must be thrilled to work on such an interesting project as this! To be able to use the latest techniques and materials and to be given such freedom in your designs is something that can’t happen very often. Contact me as soon as possible with your complete ideas and plans.

PS: My wife has just told me that she disagrees with many of the instructions I’ve given you in this letter. As architect, it is your responsibility to resolve these differences. I have tried in the past and have been unable to accomplish this. If you can’t handle this responsibility, I will have to find another architect.

PPS: Perhaps what I need is not a house at all, but a travel trailer. Please advise me as soon as possible if this is the case.

Adapted from http://public.logica.com/

Adapt Don't Implement

Adapt Don’t Implement

Context

ModelViewController style application programming.

Problems

Adapt Don't ImplementYou have some object, nicely modeled to represent your solution domain. Next, you have to visualize the object (the model) with more than one widget (view/controller). Each widget has its own set of Events, Listeners, and requires the model to implement a widget-specific model interface.

Now, you can start to implement one model interface after the other, which creates two problems:

1) The class becomes cluttered with interfaces

2) You cannot use default, basic or abstract implementations. All listener handling needs to be coded from scratch.

Solutions

Don’t implement all the interfaces at your data model. Instead, design the interface of your data model in a generic, domain-specific way.

Provide the data model with a notification/listener interface, allowing the data model to receive notifications specific to the model.

Use the AdapterPattern to provide widget-specific interfaces. Adapt the model’s get/set methods; including, the model’s listener/notification methods to the ones needed by specific widgets.

The adapter is derived from the default, basic or abstract model implementations that exist for the widgets under discussion, providing a head start for listener and event handling.
The adapters take an instance of the model as argument for their constructors.

Always Declare Serial Version UID

Always Declare Serial Version UID

If you’re making a class serializable, make it implement the Serializable interface.

Declare:

	private static final long serialVersionUID = 1;

If you don’t use serialVersionUID, the system will create one by hashing your class’s features. Then, if you change anything, the UID will change and Java won’t let you reload the old data. You can get around this later by figuring out what hash value the system used for the old class and installing it by hand – it will be some random number like:

	private static final long serialVersionUID = -403250971215465050L;

This isn’t a big problem, but it’s ugly, prone to typos and it won’t compress well. You gain nothing by postponing the declaration. You might as well use a value of 1 from the beginning.