The Tenth Principle: An idiom should not require extraordinary steps to compile or break the existing development tool set.

This is a continuation of the blog post 12 Principles of Good Software Design.

10. An idiom should not require extraordinary steps to compile or break the existing development tool set.

I guarantee this will be my most controversial comment, given how common it is for developers to want to customize their build processes to supposedly make things easier for them. And when we work by ourselves, it’s enticing to do things our own ways, to customize our environments to add new and time saving processes.

But when we work with a team, or when we work on products for a larger organization, those custom tools can create more problems than they solve. One person’s time saving plugin is another person’s confusing plugin, one person’s custom method to build a product is another person’s tool breaking dependency.

As an example, suppose you wish to integrate Maven with Xcode to automatically handle checking out and building a product. According to this article on Stack Overflow, you would need to downgrade to an earlier version of Maven. Yet when we downgrade Maven on a computer, we potentially create other dependency issues if–for example–we’re building Java on the same computer.

We also see similar integration problems with CocoaPods, as features in Xcode represent a moving target that CocoaPods sometimes fails to keep up with.

It’s not to suggest there is a problem with either of these projects. But because they are not part of the standard tool chain, sometimes the standard tool chain can break, creating problems for the development team. And those breaks must be weighed against the benefit provided by these tools. For example, project requirements may force the use of CocoaPods for third party library integration, and you just have to deal with the occasional problems that arise.

But if you are integrating just one library, the extra machinery introduced by CocoaPods may not be worth the trouble of simply downloading the library and linking directly to it.

Other problems can arise when a team doesn’t know or doesn’t use the tool chains for a particular language in a standard way.

For example, it is possible to build a Java application which is built using make, using tools such as emacs to edit the code. One could build an Android application this way, using the command-line tools in the Android application. One can–with the application of the right command line arguments–even ignore the standard hierarchical directory structure that usually accompanies a Java application.

For example, suppose we have a very simple Java program which prints “Hello World”:

package com.chaosinmotion.testbuild;

public class Main
	public static void main(String[] args)
		System.out.println("Hello world.");

and we wish to build a jar file which can be executed using java -jar test.jar.

So we create our manifest file:

Main-Class: com.chaosinmotion.testbuild.Main

And we build our Makefile:

	javac $< -d .

test.jar: com/chaosinmotion/testbuild/Main.class
	jar cmf manifest test.jar com/chaosinmotion/testbuild/Main.class

Our file directory looks like:


And when we run make on the command line we get the jar file we want.

Did I just offend all the experienced Java programmers here? đŸ˜ˆ

Yes, you can build Java applications this way. You can even build Android applications this way: all of the steps in the Android build process ultimately triggers command-line tools that can just as easily be fired from a Makefile.

But you wouldn’t want to, because it subverts the common Java development paradigms used by most Java development tools.

By not maintaining the source kit directory structure that most Java development kits expect, you cannot move your code to Android Studio or Eclipse. You can’t even easily move your code to using ant. (This was a simple one-source file example. Suppose, however, you had hundreds of java files scattered across multiple directories, directories which do not reflect the package structure declared in the source kit.)

And by not being able to use the standard tools, you miss out on a variety of features these tools bring to the table which can help accelerate your development process. For example, that make file that builds hundreds of sources means you don’t get the benefits of an incremental build and debug process you’d get in Eclipse or Android Studio. It means you wind up spending a considerably longer time to wait for a build. It means you may not even be able to leverage a source debugger tool, leaving you to using “print” statements to debug your code.

The problem with abusing development tools, especially in a large group project, is that you create all sorts of obstacles to efficiency. Now some of the plugins or additional tools we really need to use: as I noted, the occasional cost of a broken Xcode build process may outweigh the necessity of coordinating a dozen or more plugins provided and managed by CocoaPods. But think carefully before wandering away from a development environment’s “happy path”, because you may create more problems than you solve.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s