Archive for .NET

Annotations/Attributes: How do they help us?

On Thursday morning at the Cortina Software Architecture Workshop, Erik Dörnenburg held a session entitled Annotations/Attributes: How do they help us? Since I’ve written about these types of class metadata before, I was very interested in this session. Especially since every JSR that comes out of the JCP nowadays seems to add an annotation or two.

Configuration

One of the questions we covered during this talk was whether it is OK to use class metadata for configuration, as for instance a Spring bean definition file is used today. The obvious downside to this approach is that the class requires a recompilation for a configuration change. Because a class may undergo many configuration changes as it goes through its life-cycle from developer environment through testing environment to the live environment, you may need to recompile it quite often!

Martin Fowler pointed out that it is quite alright to use the metadata for configuration defaults, as long as you can override it using some other configuration mechanism. I agree with him on that one. However, it might be a bit unclear how a class is configured exactly in a particular environment: is the class metadata used or the XML configuration file?

Entity Mapping

Another usage of metadata we covered was that of Entity Mappings. Using EJB 3, or Hibernate with Annotations or XDoclet, one can define the entity mapping using metadata. I imagine .NET ORM frameworks like NHibernate have similar functionality.

The question that arises from this is: Is a entity with metadata still a POJO? The consensus in the session was that that it isn’t, since it is tied to a specific framework. This is especially true in .NET, with its strict reference resolving mechanism1.

Domain Specific Language

The final usage was suggested by Mats Helander. He suggested using class metadata for class intent, as a Domain-Specific Language of some sorts. If I remember correctly, the idea was to define one’s own metadata, and to map that metadata to the frameworks you use. The advantage over the previous approach is obvious: you are not tying yourself to a particular framework anymore, you are expressing the semantics of your classes, and map that to the frameworks you use. Obviously, the metadata could also be used for other purposes, such as DSL tools.

I find this way of using metadata really interesting, and I’m looking forward to trying it out in a project some time.

Update 2006-02-14: Erik is going to speak about Domain Annotations at the Software Practice Advancement Conference this March. Looks interesting!


1 - In .NET, if you use a attributed class, you must also add a reference to the assembly containing the attributes, otherwise you get a compilation error. In Java, with looser reference resolving, this does not appear to be the case: the class is simply not annotated if it cannot find the annotations at runtime.

Comments (5)

Annotations vs. Interoperability?

Steve Loughran, author of the interesting article Rethinking the Java SOAP Stack, has an excellent point when he says:

…everyone still falls for the lie that adding @WebService or [WebService] makes your class interop. Nobody would realistically do an enterprise application with the database table bindings defined by the developers, declared in the EJB annotations and magically interpreted by the runtime—yet nearly everyone is prepared to let the Web Services stack do that for messages.

I couldn’t agree more! Annotations are great for adding metadata to classes, but not for transparently adding behavior. Doing so will decrease flexibility (and therefore interoperability), which is really important in larger enterprise applications.

Comments (3)

Kitchen Cupboard Anti-pattern

Recently, I have come across an anti-pattern that all of us has seen from time to time. After some discussion with my coworker Uri, I decided to call it the Kitchen Cupboard Anti-pattern.

The pattern takes its name from a situation we’ve all experienced: you want to store something in a jam-packed kitchen cupboard, so you open it up, and your Rice Krispies, peanut-butter, coffee, and marmalade falls out. For a short moment you ponder whether to rearrange the cupboard, so that everything would fit more nicely, but after three seconds you decide to wedge everything in there, and quickly close the door. You silently hope that someone else will open the door next time, and that he (or probably she) will clean the cupboard up.

The Anti-pattern is quite similar: you were told to fix an application you know nothing about, so you decide to browse through the source code. It is even worse than you expected: code was copied from place to place, there are 1000+ classes; all suitable for the Daily WTF, hardly any documentation; the documentation that does exists hasn’t been updated in years, and half of the unit tests fail. You ponder whether to refactor the app, or at least the part you’re supposed to fix. But after three seconds, you decide to wedge your code in there, run the unit tests (for the part of the application you touched anyway), and commit. You silently hope that someone else will be put on the project next, and that she (or probably he) will refactor the project.

Comments (2)

What to do about TODOs

Many projects I work on are littered with TODOs, FIXMEs, or XXXs. Some programmers use these tags to remind themselves of stuff to do later on in the project. Sometimes, these programmers also comment out whole sections of code using block comments like /*, or even an #if false. To these people I say: a source code file is not a notepad.

The problem with TODOs has to do with the maintainability of the code. If another programmer looks at a class file that contains lots of task tags, he might become confused: to what degree is this class finished? It gets even worse when someone fixes the issue that is mentioned in the TODO, but forgets to remove the tag. There is nothing left to do, but the TODO remains.

Commenting out blocks of code has the same issue: a coworker has to determine why the code was commented out. Was it because it no longer works? Or because it might be useful in the future? But hasn’t XP taught us that planning upfront is the wrong thing to do?

I suppose that using TODOs has something to do with the fact that it is hard to stamp your code with the label finished. As long as there are some TODOs in there, you always have an excuse for a bug, and you never have to take responsibility.

I try never to check in anything that contains a task tag or a large code block comment. I try to keep the code 100% finished, at all times. This doesn’t mean that it does everything yet, but it means that it does everything it is supposed to do correctly. If it doesn’t, you’ve found a bug. Clear and simple.

Comments (7)

Towards an Oject-Oriented build

For the umptieth time, I am creating a build environment. And for the umptieth time, I am frustrated with the possibilities that Ant, or–in this case–NAnt–provide. To quote Alef: we’ve got ourselves a pretty decent multi-project build system, continuously integrating and all.

Right now, I’m trying to “port” this system to NAnt for our upcoming .NET-based projects. The system consists mostly of generic build files, which are imported into the project build.xml. Thus, all targets are defined in one place: a common build-common.xml file, and we don’t have to copy and paste anything. Using imports or includes is about the best you can do when you want to create a multi-project build system.

However, sometimes you want to override a target in a specific project. For instance, in some projects, I want to do a code-generation step before compiliation. In other projects I want to do some post-processing after compilation. You can’t do this generically in Ant, unless you use something like the following:

<project name=“sample” >

    <import file=“build-common.xml” />

    <target name=“compile” depends=“pre-compile, common.compile, 
        post-compile” />

    <target name=“pre-compile”>
      <!– Do code-generation step –>
    </target>

    <target name=“post-compile”>
      <!– Do post-processing step here –>
    </target>

  </project>

Note that you cannot have two compile targets, since all targets and all properties live in a global namespace, though Ant 1.6 gave imported targets a separate namespace. Also note that if you use the code generation steps in any other project, I will want to move its definition to a global import/include file too.

Now let’s say that I also want to delete the generated code when I call the clean target. So, in addition to the above, we also have to add the following:

<target name=“clean” depends=“generated-clean, common.clean”>

<target name=“generated-clean”>
      <!– Clean generated code here –>
</target>

Now imagine that I want to use three different code-generation tasks in my project (which isn’t that weird: I have had projects where I did wsdl, commons attribute, and xdoclet generation). Before you know it, you will end up with targets that are called pre-compile-custom, and post-clean-common, and whatnot. Eeek.

Imagine…

Now imagine this: an object-oriented build, where you can use the object-oriented principles you know to solve these issues. Imagine that there are common classes and interfaces that perform build tasks. For instance, there is an interface that is implemented by all tasks that can be cleaned:

public interface Cleanable {
    void clean;
}

For a project, you will probably want implement a basic Project interface and perhaps extend a DefaultProject. But in the project, you can decide where and how to override the default behavior, and use common build components to build you project. For instance, project will definitely also implements Cleanable, and its implementation will look something like:

public void clean() {
    for (int i=0; i < buildComponents.length; i++) {
        if (buildComponents[i] instanceof Cleanable) {
            Cleanable cleanable = (Cleanable)buildComponents[i];
            cleanable.clean();
        }
    }
}

Of course, too make it easier to change your project build, you will probably write in a language like Groovy or IronPython. That way, you can write the real meat of the build in Java or C#, and the rest in a scripting language. Also, there will probably be some kind of (N)Ant-wrapper, so that we can its handy tasks.

Now I know that greater gods have toyed with this idea. I read of people that deserted and returned to Ant. I even looked at Maven, Ruby and Rake. However, none of these solutions give me the satisfaction of the solution I propose above.

To be continued, I am sure…

Comments off

« Previous entries · Next entries »