Making Good Software

A blog by Alberto G (Alberto Gutierrez)

Written by Alberto Gutierrez

June 15th, 2011 at 4:38 pm

Top 10 basic java advices.

with 6 comments

1.- Make the classes that contain the logic of your application stateless.

A stateless class is a class which doesn’t have state, or which state is formed by injected dependencies used to delegate behaviour. Since these classes don’t have state, the outcome of their methods is only dependant on their input. Stateless classes have the following advantages.

  • Thread safe friendly.
  • Deterministic behaviour
  • Easy to test.

2.- Use unmodifiable beans as much as you can.

Unmodifiable beans are classes which state are set on creation and from them are prevented to change; in java, using the modifier final in your member fields best approaches this.

Unmodifiable beans offer the following advantages.

  • Thread safe friendly. Actually: stateless logic classes + unmodifiable beans = Thread safety!
  • Robustness. Unmodifiable beans eliminate the risk of holding references to objects that keep changing.

3.- Try to have your classes matching one of the following categories.

There are two main concerns a class can deal with: logic and data modelling. Having classes that deal with logic or data that don’t belong to them  make your code more confusing and cluttered. Based on these two concerns, there are mainly 5 types of classes that you should try to adhere to:

  • Service. 100% logic, publishes the main public end points of your application, they usually delegate to managers through dependency injection.
  • Bean. Mainly data model but also logic, used to carry data and perform operations, the operations the bean can perform should be self contained.
  • DTO. 100% data model, is a particular type of bean used to transport data betweeen different mediums.
  • Business logic manager. 100% logic, encapsulates the implementation of the business rules defined for your domain.
  • Integration manager. 100% logic, glues together business logic manager + external frameworks used in your project + beans.

4.- Avoid static methods.

Static methods usually contain miscellaneous logic required in your application, because is difficult to find an already existing class in the code to host them, they sometimes are created as static methods in abstract classes. It is much better to encapsulate the static methods as instance methods in utility classes such as AppUtils… The disadvantages of using static methods are:

  • They are more difficult to mock out in tests
  • Their implementation can’t be hidden behind an interface
  • They can’t be injected.

5.- Use composition over inheritance.

Inheritance heavily violates encapsulation, and easily generates obscure code. One clear example is the java io library which entirely designed with the decorator pattern. Composition allows you to have completely equivalent functionality, but without breaking encapsulation, it is also the core concept of the most important design pattern from all them all, the strategy pattern.

6.- Design in layers.

Almost every single business application has a few broad main areas of concern that are completely unrelated from each other. These areas of concern should be translated into layers in your design to allow for a cleaner code. The most common layers are:

  • Persistency
  • Model
  • Integration
  • UI

7.- Avoid child to parent, or child to sibling relationships.

Design is the art of abstracting a problem into its different entities and their relationships. These relationships most of the time express some sort of parent-child relationship, as entity A contains entity B, or entity A manages entity B. Having these relationships implemented only from the parent to the child allows for clearer an less coupled code. One clear example of this would be the way Lists are implemented in Java.

8.- Keep the invariants to be maintained by the programmer to a minimum.

Invariants are conditions that need to be kept in order for an algorithm to work as expected. For instance, constants are usually defined with Simple data types as integers, strings… and if they are used anywhere in your code, is to be expected that you will receive not any value, but the ones specified by your constants. Other examples of invariants are not so obvious, imagine that there is a service with a method process, that retrieves an order, the only parameter that should be accepted is the order id, if the method requires something else, like the creation date of the order, we are adding a unnecessary invariant to be kept by our consumers.

9.- Avoid side effects in methods.

A method should only do one thing. Methods with side effects are dangerous, as the output of the method is never clear, you should always aim for deterministic methods with no side effects and which only read their input, never change them.

10.- Test.

Test, test, test… In software development is more productive to produce 7/10 of a robust application than a completely flaky application. Based on the previous classification of classes I would recommend the following approach for testing.

  • Don’t test your beans.
  • Unit tests your business logic managers.
  • Integration tests for services and integration managers.
  • And finally… always spend some time doing manual end to end test.

10+1.- Your judgement must be above everything.

Software development is not an enginery; there isn’t a set of well-defined problems that have well-defined solutions. Is not like building a bridge, or a building… every development is unique, what applies to one project doesn’t necessarily apply to other. What this means, is that there isn’t absolutely any rule that has to always be applied, all are best practices, or advises, but is up to you to decide what approach is better suited for the problem you have to solve now.

6 Responses to 'Top 10 basic java advices.'

Subscribe to comments with RSS or TrackBack to 'Top 10 basic java advices.'.

  1. Welcome to the procedural-oriented programming: in one side you have your data (100% data model) and in other side your operations (100% logic).

    I’m not surprised as the languages used (Java, C# …) are derived from Simula; Simula has neither be an object-oriented language (most people confound class-oriented programming, which is an enhancing way of the modular-oriented programming, with the object-oriented programming; object-oriented programming is mainly a message-passing matter with a second-order typing).

    So, with such principles, other languages are more useful than Java; a functional language like Scala (to be in the JVM world) or Haskell or a modular one like Ada.

    moqui

    15 Jun 11 at 11:24 pm

  2. I think you are wrong here “There are two main concerns a class can deal with: logic and data modelling. Having classes that deal with both make your code more confusing and cluttered”.

    That is exactly one of the pilars of the object-oriented programming: encapsulate your data+logic in a class.

    Your proposal is what Martin Fowler calls “anemic domain model”: http://www.martinfowler.com/bliki/AnemicDomainModel.html

    However, I must confess that I’ve found is useful in some environments (web domain entities…)

    Guido

    16 Jun 11 at 5:02 am

  3. Couldn’t agree more with moqui, this way of designing the application is so 2004. I can’t understand why people are still trying to decouple the model and the logic. Also, this post goes against what you said in this ( http://www.makinggoodsoftware.com/2010/05/17/how-to-create-a-good-domain-model-top-10-advices/ ), 4th item for example.

    I think this can cause a long discussion about modeling and designing your application, but for me this problem root is the old j2ee specification, and the patterns used for those applications.

    At that time, for example, if you’re using ejbs you were forced to extend and implement specific interfaces, making it difficult to create a real good model, that’s why everybody was creating the logic classes (session beans) and the vos and dtos to carry the data arround.

    Things have changed, new solutions have arrived but people are still thinking in the same way they did in 2004.

    Matt

    16 Jun 11 at 5:42 am

  4. @Moqui, Guido and Matt.

    Thank you guys for your opinions, specially to Matt for proving me wrong using my own arguments… I can only say touché…

    I see that I wasn’t clear on my article… I wasn’t suggesting that we should approach Java as a procedural language, or I wasn’t trying to defend an old school type like design… I am very much in favour of rich domains…

    When I mentioned that you should divide logic and data model I meant it for objects which shouldn’t selfcontain their ow logic, for instance… Imagine an order class with the method send, or revoke… Is obvious that the order doesn’t have enough knowledge to perform these operations by itselt, so these methods should be placed elsewhere.

    I see now that I wasn’t clear, so I will reprhase it… Thanks for pointing this out for me.

    Alberto Gutierrez

    16 Jun 11 at 6:59 am

  5. Hi Alberto:

    I don’t have my own blog so I will just blurt my opinion on yours!

    Firstly, I agree with all your points. I think what you mention are good software dev principles. But maybe we need to ask why these points need to be mentioned over and over again. If it were so clear, why don’t we all learn it and stick to it?

    I think there are many reasons but I’ll give you three. First is that oo programming and design have conflicting principles/rules of thumb. For example, should you separate logic and state? On one hand, minimizing side-effects and the ability to share functions/methods compels you to separate them. On the other hand, this leads to anemic domain models therefore it’s bad. There is a great tendency to split classes up to make sure it has only one concern but the more you do this, the more classes start to look like they’ve been split into two groups- ones which hold state and others which hold functions. So we balk at that and we go back to thinking about sticking them together. Helper classes are an example of this sort of ‘separation of concerns’ exercise.

    The second reason why we make can’t program ‘properly’ in java is because it doesn’t do a good job at helping us do so. Collections and many value types (Dates for example) are mutable. We have to do extra work to make things immutable. Also, the whole principle of oo is based on side-effects. This isn’t a java-only problem obviously. Changing a value of a field in a class is a side-effect. It isn’t easy to follow the no side-effect principle if oo itself is based on storing and using side-effects. Java is also missing features such as first-order functions and mixins which help with this and inheritance/encapsulation issues.

    The third reason is that we think we need to program every problem with an oo solution. One can argue that certain applications fit the oo model such as GUI programming. Others not. Maybe we ought to think of dividing the layers or components of the application stack into oo vs non-oo (functional). Your blog certainly implies we do so. In so doing, we can give up the sacred belief that all objects must contain state and behavior. It is ok to have anemic classes. Maybe we even use other jvm languages where it fits better. Not that that will go over well with your boss…

    Cheerio
    Mike

    Mike

    8 Jul 11 at 2:49 pm

  6. example pleaseee?

    arnold

    16 Nov 11 at 2:12 pm

Leave a Reply