Modern Web Development

In the last few years web technology has lived through rapid growth and heavy change. We went from frames to table layouts, to column layouts, to responsive layouts. From html4 to xhtml & flash to html5. From heavy server to rich client. From rpc to soap to rest. From sql to nosql and big data. From MVC to MVP and so on. In the following post i want to describe what has become state-of-the-art from my perspective.

A Backend is a REST api 

Every backend should be seen as a REST api and every controller as another resource. You want to analyze your problem domain, find your resources and design proper paths for them. They become the M in your MVC Architecture. Developing a webapplication first, and adding an extra REST api later on has to be considered an antipattern. If you do make a REST api, you want to consequently use it yourself, making your frontend its first consumer. This procedure allows you to smoothly add different kinds of clients later on, such as a mobile app or even a desktop application. It's also the foundation to integrate your applications features into other applications.

Separate your Frontend

The days when you made up a form using jsp with a jstl form validation are fading. You don't want to mix client with server technology anymore. The V and C of MVC has shifted over to the client and your backend just represents the Model. You want your frontend to be completely separated using client technology only (html/css/js) and consuming your REST api. GUI logic, building and aligning proper html elements can be achieved within javascript. The most appropriate content-type for information exchange between the backend and frontend would be json or even xml.

Rich Client & Hail JavaScript

The MVC pattern is nowadays implemented on the client side using javascript and it's fellow frameworks. There is no full-blown complete javascript framework that can achieve everything out of the box, but there are tons of smaller libs solving atomic tasks. This should not be considered bad or overwhelming, but advantageous. It causes a great variety of tools that focus on solving single problems outright. Backbone is a popular mvc framework built upon underscore, a js library delivering great utility with remarkable functional programming features. A template engine like mustache or handlebars could be added and requirejs would manage the dependencies within your modules. Of course, a dom manipulator like jquery cannot be left out. The trend is leading towards SPA's (Single Page Applications) with heavy AJAJ/AJAX, routing through html #anchors representing bookmarkable view-states.

Implement a Buildprocess for your Frontend

As Browsers are continously increasing javascript performance and adding more and more support for html5, frontends have become complex and sophisticated. You now want to add a build process for your frontend, compiling all your js and css files. You want to deliver only a single minified js file to the browser. Other than that we don't break the DRY principle writing styles anymore. We use dynamic stylesheet languages like less to make our styles smarter and cleaner and compile them to css in our build process. Node and rhino are possible engine candidates to build your frontend. While node is much faster, it requires an easy installation on the build server. Rhino runs in a jvm, thus not requiring an installation. You can add it to your project as a maven dependency.

Mobile Web & Responsive Design

Mobile devices are becoming more powerful in terms of hardware whilst html5 support is also rapidly increasing on mobile browsers. Html5 could potentially make native mobile applications obsolete one day. Localstorage, SQL, Geolocation, Multimedia, Camera Access, Web Sockets, Graphics, Touch Events, WebGL, Filesystem Access, Notifications and many more are all features to be completely available to mobile html5 webapplications one day, hopefully working on all devices. So far, we have been developing multiple applications for android/ios/windows mobile and so on, being an economic nightmare.
Mobile clients have gained a substantial amount in web consumership, and cannot be ignored anymore. Therefor you want to make your GUI reponsive, beeing able to scale down to smaller display-resolutions. Wise companies have even started designing userinterfaces for the smallest resolution before even thinking of a desktop resolution. This makes scaling more easy, since the other way round is harder and tends to force painfull workarounds. Bootstrap is one of many libraries that help you make your gui responsive. You can use initializr to get started.

GWT or ZK Framework? Use Neither!

GWT/ZK are trying do deliver a framework that makes it possible to develop modern ajax web applications using Java only. So they are basically building a java wrapper for frontend technology. Other than that, they deliver a huge amount of components. BUT ... i'd like to question their philosophy for many reasons.
  • They Both produce quite bad html code making you end in an element and dom-id nightmare that gets hard or even impossible to test, debug and style. Html5 allows to write short, clean and readable code, organized way better. You want to write html yourself.
  • Their AJAX calls are not based on the REST api that you need. If you want a REST api, you may have to write that again. RPC is GWT's primary communication-technology and i am really concerned about that. But you can still make a REST api work with GWT if you like to.
  • They keep you away from the technology that you are actually producing. Tiny customizations can get hard or even impossible in the end. You are basically giving up control and limiting your possibilities. This might in many cases lead to dead ends, that are based on the framework, not the technology. GWT helps to overcome this problem offering JSNI.
  • They are never up to date. While browsers are evolving rapidly, new features have to be implemented in the Java-Wrapper before you can even use them, delaying your up-to-dateness.
  • I doubt that wrapping native front-end technology is a good idea, and i don't see a reason for doing it. One pro GWT argument might be: it's generating optimized JS code.
In the end they make it easier to build webapplications for former java.awt/swing developers, who have no to little knowhow on html/css/js.
They defintively have their place right now and aren't a bad choice in some cases.


to the comments

What makes a great Developer

    Passion

    It's the taste of success that comes with every little task that you've mastered, and smart solutions you've found that turn out advantageous. Programming is not just a job, it's an Art - it's Poetry. With Passion comes Motivation and thus Progress. Software development is not only huge, but also evolving very fast. A good developer enjoy's keeping up-to-date, since he knows that there's always a better way to do something. Learning new ways, satisfies his hunger.


    Curiosity

    A Program is deterministic. There is no such thing as an accident in a computers world. Every effect has its cause. A great developer does not accept accidents. He'd rather search and debug the numerous layers of a Software and it's environment to find the very reason. He builds up deep knowledge by doing that, allowing him to better understand, read and interpret weird behaviour of an application. A good developer does not program by Accident.

    “The important thing is not to stop questioning. Curiosity has its own reason for existing.” - Albert Einstein

    "The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents." - 
    Nathaniel Borenstein



    Cognition

    Programming is the act of solving a problem. Problems can be factorized into multiple parts that work together as a whole. To find and reflect those in your mind, and imagine their interaction is a true skill. There is nothing more to say about that.


    Meticulosity

    Programming is full pitfalls that can be tracked down to the very microcosm of Software Development. The Devil is in the details, and even the smallest sluttery can easily tear a Project down. That's why perfection is so powerful, and important for high quality and success. If you accept a single flaw, you will most likely accept a second, ... and a third ... until you got a mess. A good developer cannot accept flaws and thus avoids many pitfalls increasing quality. There is an analogy to the Broken Windows Theory, which basically says that a single broken window can easily lead to more serious deviance, crime, abandonment and demolishment of its house.


    Time

    Greatness comes with experience. It's the iterations of improvement that have been lived through, that really matter. Yes, you can simply follow advices, patterns and best practice. But that has nothing to do with Wisdom, which evolves by doing mistakes and iterations.


    Humbleness

    A great developer knows that he doesn't, and will never know everything. He knows, that there is always room for improvement, also in his own work. He admits his mistakes and accepts critisism.


    Tenacity

    A good developer declares war on every workaround. He will fight it even if he has to struggle hour after hour, through the night, until the sun rises. Even the greatest developer meets problems, that he might not consider solvable in the first place. But he takes it as a challenge, unless it's not an antipattern. "It won't work" is not an option. Hard-earned success evolves self-confidence.

    Vision

    In Software development, it is common to work long times on small tasks. While beeing focused, it's easy to get lost and overlook the impact on the rest of the system. A good developer is skilled in keeping an eye on the bigger picture, foreseeing sideeffects of a current decision. Still he may intentionally choose to postpone their treatment going step-by-step.


    Lazyness

    This might sound stupid in the first place, but its not. Lazyness leads to a lot of improvements. The probably most important thing it leads to is Automation. Everytime you have successfully refused to do something manually by automating it, you have already improved. Automation is the key to faultlessness, efficiency and progress. Faultlessness, because ideally a computer doesnt make any mistakes (which is not entirely true in every aspect), but humans do real quick. Efficiency, because it's an investment saving time in the long run. The earlier you automate something, the more you get out of it. Progress, because every process that does not demand mental resources anymore leaves room for something else. What you don't have to think of doesn't hinder you, whereas software development is actually completely blown up with barriers that you have to think of all the time.

    A good developer is too lazy to
    • write a complete API doc, he lets JavaDoc do the job.
    • format his code properly, he lets his IDE do the job.
    • test a functionality over and over again, so he automates it using xUnit. 
    • read complicated methods, so he writes short readable methods with good names.
    • write the same lines of code all over again. He seeks for ways to refactor to avoid such boilerplate code, since he is too lazy to repeat himself. (DRY)
    • implement that functionality that nobody asked for. (YAGNI)
    • use bitwise shifting for a subtraction, he keeps it simple stupid (KISS).
    • write code at all, he lets his colleague do it for him (Pair Programming).
      Nah, i was just kidding on this one ;-) 

    What do you think makes a great developer?


    to the comments

    The Art of Naming


    1
    2
    3
    4
    5
    6
    7
    8
    public class Handler {

    private String data;
    private String temp;

    public int c(int a, int a2){
    int result = a+a2;
    //...


    Why is Naming so important?

    Because its a matter of Quality.
    Naming = Readability = Understandability = Maintainability = Quality.
    Good Names make your code readable, which is an essential feature for every person that has to work on it, including yourself. Soon after written, you'll forget about the details. Getting into it and understanding again can be tough and frustrating. The right Names will redeem yourself and others from those barriers. You'll might think for yourself: "No!!! I don't have the time to make this all clean and perfect. I just have to get the thing done as fast as possible, and it's no problem because i won't have to deal with it after its finished anyways..." - That's just wishful thinking. Software never ever becomes completed. Thats part of its nature. In fact, the opposite is the truth: By choosing the right names carefully, you save a lot of time from the very first day on. You keep your mind free of needless noise that slows your progression down.

    How to choose the right Names?

    According to "Clean Code", Names should:
    • Be intention revealing
    • Avoid disinformation
    • Make meaningful distinctions
    • Be pronounceable
    • Be searchable
    But i'll add one point
    • be unmistakable (which might already be part of avoiding disinformation)

    Be skeptical about a name in the first place, and dont accept it until every bit of skepticism has been eliminated. Complete Words are usually better than Acronyms, AND .... avoid redundancy!!

    1
    2
    3
    class Book{

    public String[] bookPage; // Don't repeat book since its given in the classname!

    The art is to combine good names so that your code becomes a meaningful, selfdocumenting story.

    1
    if(plant.needsWater()) gardener.water(plant)

    Classes, Interfaces and Abstracts

    Stay away from 'Manager', 'Handler' and the such. 'SomethingManager' doesn't mean anything specific and is clearly not unmistakable. Use Design Patterns in your Names. They are common knowledge and give a good information about what a Class is doing. Eg.: ShadowedBorderDecorator. Name Interfaces as what they are, and don't add Pre- / Suffixes to them (IFoo, BarInterface). Client-classes don't care if they work on Interfaces or Implementations. And it's not the Names job to indicate it's Type. You dont name a Variable intNumber either, do you? It's a violation of the DRY principle. Using Abstract in a Classname is debatable. While it's pretty common, it still violates the DRY principle. Decide for yourself.

    Common Errors in Variablenaming


    Repeating Type in Variablenames:

    1
    2
    3
    4
    Timestamp creationTime;
    Date date;
    String[] bookArray;
    SomeType somethingObject

    Adding "is" as a Prefix to booleans:
    isActive. So the getter becomes isIsActive() or what?

    Consecutive numbers.
    There is nothing harder to read than a calculation using a1, a2 and a3 multiple times.

    Generic names:
    temp, data, other, object, result, value and so on

    Inconsistency:
    Mixing multiple Naming Strategies, or choosing one without 100% sticking to it.
    E.g.: Mixing camelCase with under_scored


    to the comments

    Master the unpredictable

    Have you ever come to work on a Project that you cant quite overlook? Are Requirements not yet clear or changing fast? Here are some tips to get along.

    Use Tracer Bullets

    Don't specify your software to death. Just grab your best idea, and give it a shot. Tracer Bullets are similar to Prototypes with one very important difference. Prototypes are built to proove something, and then be thrown away. They are not intended for real production. Even some drawing on a paper could be a prototype. A Tracer Bullet might get thrown away, but it is not intended to in the first place. It is developed as stable, clean and complete as needed, to use it for real production. A Tracer Bullet that hits its target, becomes a trunk.

    Develop Leaves first

    What do i mean with a leaf? Leaves are small exchangable software components or modules, that can be written independently, tested in isolation, and sometimes even run autonomous. They only perform a very specific task, not more. Find the leaves in your Project, and start developing the leaf with the highest risk.

    Dont Reinvent the Wheel

    99% of the problems that you face in your project have already been solved. Solving these by yourself can easily become a waste of time. Even the most trivial seeming problems are not trivial at all. Underestimating those is the issue in the first place, nevertheless it happens all the time. Well, its just logical to understimate the unsolved as you cannot know all the details until you solved it yourself. Analysing the problemdomain, concepting and realizing a solution can be a great way to learn, but is not very beneficial. Its in fact a risk, since it can lead to misconception or become a timeconsuming task that exceed your resources. You might even have to throw away your first attempts. Also, your outcome would be buggy, whereas established opensource software is usually stable thanks to its brave communities.
    "Make or Buy" was a common phrase. I think it should be "Make or Find" by now, since opensource got really big. Rather invest your time into research opensource, and stay skeptical with what you find. When you compare 3rd party software, consider
    • Stability: Is it still beta, or did it have some stable releases yet? Who is the organization behind? Is the code clean and tested?
    • Activity: Can you find out how many developers this software has? When was the last commit? How frequently do they release a new build?
    • Support: Does it offer a good documentation? How about examples? Is there a public Issue Tracker? How many issues have been submitted yet and how many have been solved? Is there a Forum, literature, and a big community? Are there any big names that use this software?
    • Critisism: Is there anything bad that you should know in the first place? Search for reliable critiques and comparisons.

      Estimation is a waste of time

      Every hour that you invest in estimation, could also be invested in producing real outcome. Your estimation will be inaccurate anyway. When requirements change, you even have to change your estimations. If you have to estimate, because the business needs it, try to split your project into smaller independent parts first, and multiply your estimation with a risk factor (times two for example). In the end you`ll need it.



      to the comments

      Standalone Java Webapp made easy with Maven

      Introduction

      As you may already know, creating a war archive and deploying it on a preinstalled Servlet Container is not the only way running a Java webapp, since you can also embed the Web-Server in the application itself. Sometimes such artifacts are delivered as standalone executable programs that can be easily started and stopped in the commandline and even run as a service in the background. Maybe you should also consider producing your app this way and benefit from its huge advantages:
      • No preinstalled Webserver/Servlet Container required that would take additional maintenance.
      • Easy Cross-Platform. Same artifact can of course be run on any System.
      • Complete Standalone Software
      Apache Sonar is a great Example of such Software. It uses an embedded Jetty Server and creates an embedded H2 Database for persistence that can be replaced in configuration. As you can see here they prepared startup scripts for any Platform that execute the actual StartServer class.

      Embedded Tomcat

      In my tutorial ill use an embedded Tomcat as a Servlet Container. So we want to add the Maven dependencies first.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      <!-- embedded Tomcat -->
      <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>7.0.37</version>
      </dependency>
      <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-logging-log4j</artifactId>
      <version>7.0.37</version>
      </dependency>
      <dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-jasper</artifactId>
      <version>7.0.37</version>
      </dependency>

      We can use them now to create a StartServer class

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      public final class StartServer {

      private StartServer() {
      }

      public static void main(String[] args) throws Exception {

      // We will set the basedir Systemproperty accordingly when running the Program
      // Actually the mavenplugin appassembler will do this for us
      String basedir = System.getProperty("basedir");
      String webappLocation = new File(basedir + "/webapp").getAbsolutePath();
      int port = 8080;

      Tomcat tomcat = new Tomcat();
      tomcat.setPort(port);
      tomcat.addWebapp("/", webappLocation);
      tomcat.start();
      tomcat.getServer().await();
      }
      }

      Exploded War

      Now we need to make an exploded war in our "target" directory. I choose to create a folder inside "target" that holds the application as a whole including bin files, configuration and the webapp itself. This makes it easy to transport the complete app to another machine.
      • src/...
      • target/myapp/bin
      • target/myapp/conf
      • target/myapp/webapp
      Ill include the maven-war-plugin to create the exploded war.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.3</version>
      <executions>
      <execution>
      <id>war-exploded</id>
      <phase>package</phase>
      <goals>
      <goal>exploded</goal>
      </goals>
      <configuration>
      <webappDirectory>${project.build.directory}/myapp/webapp</webappDirectory>
      <archiveClasses>true</archiveClasses>
      </configuration>
      </execution>
      </executions>
      </plugin>

      If you run mvn clean package right now you should get your webapp compiled into target/myapp/webapp

      Startup Scripts

      Finally we need startup Scripts to actually run our application. We need a shell script for unix Systems and a bat file for Windows. The Appassembler maven plugin comes in handy here. It is a very thoughtout plugin that creates exactly what we need and even sets the basedir Systemproperty. I'll configure it to use our exploded webapp and StartServer class.


       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>appassembler-maven-plugin</artifactId>
      <version>1.3</version>
      <configuration>
      <assembleDirectory>${project.build.directory}/myapp</assembleDirectory>
      <repositoryLayout>flat</repositoryLayout>
      <repositoryName>webapp/WEB-INF/lib</repositoryName>
      <generateRepository>false</generateRepository>
      <copyConfigurationDirectory>true</copyConfigurationDirectory>
      <configurationDirectory>conf</configurationDirectory>
      <programs>
      <program>
      <mainClass>com.myapp.StartServer</mainClass>
      <name>myapp</name>
      </program>
      </programs>
      </configuration>
      <executions>
      <execution>
      <phase>package</phase>
      <goals>
      <goal>assemble</goal>
      </goals>
      </execution>
      </executions>
      </plugin>

      Done. Appassembler now creates executable scripts for all platforms inside the target/myapp/bin directory. You could even put configuration files into src/main/config that would be copied into target/myapp/conf automatically by the plugin.

      Result


      If we run mvn clean package now we get a completely transportable standalone webapp in our target directory!


      to the comments

      I18n of JPA Entities

      Sadly the support for i18n for Entities in JPA is actually very poor to non-existent. There's just basically no out of the box solution provided by Hibernate & Co, although i18n is a feature that could be considered mandatory for a powerful ORM Framework. If you take a look at PHP for example Doctrine supports i18n very well. So besides some really unpopular i18n extensions on forums/github you are basically on your own.

      So how do you do it?

      There isn't really a general solution to achieve i18n. There are many different ways and you have to choose which is actually best for you. If you do have a relatively small amount of data and ordering by translations is not necessary you can store "keys" in your tables that are being translated by Spring i18n for example. Spring i18n could store the translations in separate property files. Since you wont have to worry about performance, this is a very easy way to achieve i18n.

      But lets say you have lots of data, and you need to order it on the database side. With such requirements you are better off storing translations inside your database tables. While there are guides, and also an opensource framework on the internet that implement i18n with one centralized translation-table that holds all translations i highly recommend not to follow that idea. The problem with this solution is, that you will have to add one more join for every field that has to be translated, whereas multiple joins for a single table with lots of data can easily become a performanceissue.
      Its better to follow the approach to create a separate translation-table for every entity. This means that you would have one entity containing simple data, and another one containing only the fields that require translation. Like so:

      This schema is pretty normalized and you only have a single join on fetching an entity, while you can still order appropriate.

      Your entities would look like this:

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      @Entity
      public class Book {

      @Id
      private int isbn;

      private String author;

      private Date releaseDate;

      @OneToMany
      @JoinColumn(name = "isbn")
      private List<BookTranslation> translations;

      // constructor, getters and setters -...

      }

      and that

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      @Entity
      public class BookTranslation implements Serializable {

      @Id
      private int isbn;

      @Id
      private String locale;

      private String title;

      private String description;

      // constructor, getters and setters -...

      }

      You could then fetch a book with its translations with:

      select b from Book b join fetch b.translations bt where bt.locale = 'de';

      If you cannot accept your ServiceLayer to deliver two entities for every Book only because of translations, i suggest you to implement some DTO like this BookTO which holds all values.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      public class BookTO {

      private int isbn;

      private String author;

      private Date releaseDate;

      private String title;

      private String description;

      }

      You'd just need to map the values of Book and BookTranslation to BookTO within your ServiceLayer and also return BookTO instead of Book in your ServiceLayer.

      This solution might not always be the most appropriate, but it definitely comes in handy sometimes.


      to the comments

      Automatically generated Class Diagrams using Maven & UMLGraph

      Drawing Class Diagrams preemptive is sometimes nice to optimize your thought of design. But it will still most likely change in the development phase. Since your Class Diagram is part of your documentation it should be up to date all the time. There is no point in having a Class Diagram if the code does not fit it. You could keep adapting the changes to the Class Diagram by hand, but that can get very time-consuming and exhausting. You should rather automate that process, and there are several ways to achieve exactly that. You could for example search for a UML Class Diagram Tool supporting roundtrip engineering. There are some commercial, and even some free ones available. Not all of them work very well and it can be a frustrating task to figure out which way to go. You would probably try out some and throw them away because they are just not what you expected.
      Thats why i want to show you a different approach: Letting a Javadoc Doclet draw the Class Diagrams in build phase and embed them into your javadoc automatically. UMLGraph is such a doclet. It analyzes your code, draws Class Diagrams automatically and embed them into your javadoc.

      Since maven can run javadoc at build phase it's perfect. You just have to configurate the maven-javadoc-plugin to use UMLGraph.

      Configurate Maven to use UMLGraph


       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <reporting>                                                                              
      <plugins>
      <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>2.9</version>
      <configuration>
      <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>
      <docletArtifact>
      <groupId>org.umlgraph</groupId>
      <artifactId>umlgraph</artifactId>
      <version>5.6</version>
      </docletArtifact>
      <additionalparam>-views -all</additionalparam>
      <useStandardDocletOptions>true</useStandardDocletOptions>
      </configuration>
      </plugin>
      </plugins>
      </reporting>

      Beware that the javadoc doclet api has changed from jdk 1.6 to jdk 1.7 and most of the online tutorials are outdated because of that. UMLGraph adapted to jdk 1.7 since version 5.5.

      If we run mvn site right now, we will just get that error:
      java.io.IOException: Cannot run program "dot": java.io.IOException: error=2, No such file or directory 
      This means that the program dot was not found which is a part of the graphviz library.
       

      Install Graphviz

      For UMLGraph to run you need graphviz installed. Go to the Download Page, and choose your package. On linux you could even sudo aptget install graphviz. Beware that you might have to reboot or relogin to use graphviz, because the Systems Path is extended during installation.

      First Result

      Run mvn site, and open target/site/apidocs/index.html afterwards.


      As you can see its drawing beautiful and accurate UML Class Diagrams.

      Custom Configuration

      If you dont want attributes/methods or other extras you are totally free to configurate those graphs. See Class Diagram Options. Just add them to the
      <additionalparam>-views -all</additionalparam>
      tag in pom.xml


      to the comments

      8 Things you should not be afraid of as a Developer

      Change

      In Software Development there is no such thing as stagnancy. Everything you develop now is just another version of a component that will probably change in the future. Change is the most common thing in Software Development, and you're better of accepting it as a fact. Expect future changes to everything you develop, and therefor design your Code more modular. This makes changes more easy and increases the Quality at the same time. Adapt the concepts of DRY and YAGNI. You will often come to the Situation, where you look at your Code and imagine that you could have done that "better". Don't let this thought prevent you from sleeping. Take action immediately and Refactor! If you don't do it now, you will probably never do it. The longer you wait, the harder and more costly it gets. And you slowly grow up a mess you cant deal with anymore.
      "Good code is code that is easy to change. Code tends to change until it is no longer easy to change. All code becomes bad code." - Unknown

      Removal of dead / commented out Code

      If you experience dead or commented out code that is not required anymore, but you dont want to delete it because you dont know if you'll still need it in the future - DELETE IT RIGHT NOW!! Its your versioning tools's job to remember that code, not the comment's!!!! I've seen too much software filled with tons of commented out Code that no one can even remember any more. And then if you cant remember, you are easily even more afraid to delete it. Well, just delete it - now - for real.
      "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away." - Antoine de Saint-Exupery

      Making Mistakes

      Nobody is perfect and everyone makes mistakes. Making mistakes is a process of learning. There is no improvement if you don't make or recognize any mistakes. So: Everytime you make a mistake, you learn something new greatly improving your knowledge. The more mistakes you make and recognize the better you get. Also, there is no point in hiding your mistakes or feeling ashamed for them. Being honest and frankly about your mistakes makes you a great character and a reliable colleague. Therefor criticism, in a constructive way, is an important tool for successful teams.
      "Anyone who has never made a mistake has never tried anything new." - Albert Einstein

      Showing your code to others

      Are you afraid of other people reviewing your code? Why is that? Did you not write as good as you could have? Well, then its probably not an adequate job for you. Are you afraid that you have made any mistakes? Well you shouldn't - because you could benefit of every mistake that you have made that is found in the review - see "Making Mistakes". You should always write your code as thoughtful as you can. Therefor you should rather be proud of what you have written, and not be afraid of others having a look at it.

      Failure

      And this is one of the most important. If you come to a point where you dont see any solution for your problem: Never give up hope. Take it as a challenge. Try to see things from another angle or explain to other people. Maybe you are just stuck in the wrong perspective. Successfully solving this ridiculous puzzle will make you an even stronger Developer.
      "I have not failed. I've just found 10,000 ways that won't work." - Thomas A. Edison

      Your own codes stability

      Everyone knows this situation. You come to present your project to your boss or the customer, and you start worrying: "Will it work this time!? Hopefully i havent overlooked anything in the process of development!". This is a bad sign, and you shouldn't have to worry. You should rather have tested your project deliberately earlier. Of course, You can never make  100% sure that it works perfectly. But you can greatly improve the trust in your code by writing automated tests. It makes you feel more comfortable adapting changes and showcasing your software.

      New & Complex Technology

      Developers are lazy and often sit on their "good ol" technology way too hard. IT is improving incredibly fast, new and better technology is born every day. Be open minded, read blogs and stay up to date. If a technology/framework seems to exactly fit your needs, give it a try. Also show it to your colleagues an spread the word. This is a great story about developers being afraid to try something new.

      Fighting Time Pressure

      Do not ever let time pressure ruin the Quality of your Project. It is your Job to keep your Code clean and stable. Quality requires deliberate decision making and takes time. And sometimes you need to fight for it. Your customer expects a 100%, maybe even 120%, complete Product that is maintainable and state-of-the-art. If you let the quality down and deliver a poor Result, you will end up in even more changerequests, maintenance effort and distrust. The time you saved earlier will be eaten up by the technical debt that you allowed. Also if you allow a single leak, the inhibition of allowing many more significantly drops. Be honest with your boss and show some backbone when it comes to Quality.
      "Programming is like sex: one mistake and you’re providing support for a lifetime." - Michael Sinz


      to the comments

      Wanna Cache? Decorate!!

      The Decorator Pattern

      Class Diagram:

      Decorator Pattern is one of the most powerful Design Patterns, and its important to understand why. It allows you to add functionality to a Class without changing it. You use delegation instead of inheritance by just wrapping the existing Class in a "Suite" of your choice while the Interface stays the same. This way, you can even wrap a Class into multiple layers of Decorators where every Layer has its own and different purpose, and the Original Class even stays the same. Other than that the Layers are completely interchangeable and removable, because they all have the same Interface.
      You can use your naked Object in the same manner as a decorated one with multiple Layers, and the rest of the Application wont even notice. Other components dont need to know whether a Class is decorated or not, because the only thing they care about is the Interface. The following Graphic should clear things up:
      Just follow the Steps:
      In the first example there is no Decorator. So SomeClass directly speaks to BookService
      In the second example there is a single Decorator. Therefore the following steps apply
      1. SomeClass calls SomeDecoratorA.
      2. SomeDecoratorA delegates the call to the real BookService. The Decorator could even manipulate the call in this step.
      3. BookService returns a result. SomeDecoratorA now holds the result, and may manipulate it.
      4. Finally, SomeDecoratorA hands the result over to the original caller SomeClass.
      In the third example, there are even 2 Nested Decorators. Since every Decorator speaks the Interface of the BookService Class you can wrap an infinite amount of Decorators upon.

      Usage Examples

      Most examples in Books and online Guides describe the Decorator Pattern used by some Graphic related stuff. You would have a normal line, and a line decorated with a shadow. Another example would be a Window in a GUI where you vary Decorators that add different kinds of styles (e.g. different Colors).

      But its important to understand, that Decorators are not intended to just make Styling more dynamic. It is just one way to use them. Instead, there are many more great use cases for Decorators and i will show you an example applying cache functionality.

      Applying Cache with Decorator Pattern

      Class Diagram:

      As you can see i am adding a BookServiceCacheDecorator that holds a Cache Component which temporarily stores a List of Books. The BookServiceCacheDecorator in the first place asks the Cache if there is a result available. If thats true, the decorator will use the cached result. Otherwise it will fetch the Result of the BookService itself, and store the Result in the Cache for later use.

      I start with the BookService Interface,

      1
      2
      3
      public interface BookService {
      public List<Book> findAll();
      }

      and its prime implementation.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public class BookServiceImpl implements BookService {

      @Override
      public List<Book> findAll() {
      System.out.println("load new data");
      List<Book> books = new ArrayList<Book>();
      books.add(new Book("BookA"));
      books.add(new Book("BookB"));
      books.add(new Book("BookC"));
      return books;
      }
      }

      Here is the Code of the Cache Class. In this example it's caching forever, but thats alright.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      public class Cache {

      private List<Book> storage;

      public void save(List<Book> books){
      this.storage = books;
      }

      public boolean hasResult(){
      if(storage != null){
      return true;
      }

      return false;
      }

      public List<Book> load(){
      System.out.println("load from cache");
      return storage;
      }
      }

      Now lets continue with the Decorator Base Class. It has a preemtive Constructor to hand over the decorated Object.

      1
      2
      3
      4
      5
      6
      7
      8
      abstract public class BookServiceDecorator implements BookService{

      protected BookService decorated;

      public BookServiceDecorator(BookService decorated){
      this.decorated = decorated;
      }
      }

      And finally the CacheDecorator. It Checks the Cache before calling BookServiceImpl.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      public class BookServiceCacheDecorator extends BookServiceDecorator {

      private Cache cache;

      public BookServiceCacheDecorator(BookService decorated) {
      super(decorated);
      }

      public BookServiceCacheDecorator(BookService decorated, Cache cache) {
      super(decorated);
      this.cache = cache;
      }

      @Override
      public List<Book> findAll() {
      if(cache.hasResult()){
      return cache.load();
      }
      List<Book> books = decorated.findAll();
      cache.save(books);
      return books;
      }
      }

      Now two different use cases. One without Decorator, and one with the Cache Decorator:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      BookService bookService = new BookServiceImpl();
      bookService.findAll(); // prints: load new data
      bookService.findAll(); // prints: load new data
      bookService.findAll(); // prints: load new data

      BookService cachedBookService = new BookServiceCacheDecorator(new BookServiceImpl(), new Cache());
      cachedBookService.findAll(); // prints: load new data
      cachedBookService.findAll(); // prints: load from cache
      cachedBookService.findAll(); // prints: load from cache

      Thats basically it. Just read the Code carefully. The final use cases should make clear how the Decorator applies functionality. Decorator pattern really helps you create a very modular Code in many circumstances. You should not be afraid of the additional Classes the Pattern depends on, since they are really not a big deal. The modularity gained easily outweighs them.


      to the comments

      Avoid too many Parameters using the Builder Pattern

      Today i want to show you another way to use the Builder Pattern. From what i've seen there are tons of examples of the Builder Pattern online. But they do all have one thing in common: They are used to create an Instance of an Object and "replace" its constructor. This way you can create a complex Object in a very clean and readable fashion using a Fluent Interface.

      Other than that, there is also a slightly different way you can benefit of the Builder Pattern. Think of a Method with like 10 Parameters. Thats not quite nice, and should not ever happen. Robert C. Martin recommends a maximum amount of 3 Parameters in his book: Clean Code. You should rather use some kind of a Config Object holding those 10 parameters, to clean it up. But lets say, you have a BookService Class with a find(..) method, that allows to search by 10 different parameters, and every single one of them is optional. You could use the Builder Pattern with some kind of Query Object to solve the problem.

      As we should always program against Interfaces to keep things modular, ill start with the Interface:

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      public interface BookService {

      public Book create(Book book);

      public void delete(String isbn);

      public Query query();

      public interface Query {

      public Query isName(String name);

      public Query hasAuthor(String author);

      public Query isCheaperThan(Float price);

      public Query isIsbn(String isbn);

      public Query hasMorePagesThan(Long pages);

      public Query isAvailable();

      public List<Book> find();

      }
      }

      So the Interface looks pretty neat. It allows you to write something like:

      bookService.query().hasAuthor("Bob").isCheaperThan(20.9).isAvailable().find();

      While the Query could be considered as an implementation of the Query Object pattern it is not tied to any Database related stuff, which is very important. You dont want to be tied to Criteria Queries or SQL in this Layer. It should be independent of any implementation (e.g. Database or Filesystem).

      To clear things up, i want to show you an implementation example using Spring-Data. I am a big fan of Spring-Data, since it allows you to create full featured DAOs with little to no Programming effort for many different Persistence Providers. If you havent used it yet, you should definitely give it a try.

       1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      @Transactional
      public class BookServiceImpl implements BookService {

      @Autowired
      private BookRepository bookRepository;

      // ...

      @Override
      @Transactional(readOnly=true)
      public Query query() {
      return new QueryImpl(this.bookRepository);
      }

      public class QueryImpl implements Query{

      private BookRepository bookRepository;
      private Specifications<Book> filters = null;

      public QueryImpl(BookRepository bookRepository) {
      this.bookRepository = bookRepository;
      }

      private void addFilter(Specification<FlowMessage> filter) {
      filters = (filters == null) ? where(filter) : filters.and(filter);
      }

      public Query isName(String name) {
      if (name == null) return this;
      addFilter(BookSpecifications.isName(name));
      return this;
      }

      public Query hasAuthor(String author) {
      if (author == null) return this;
      addFilter(BookSpecifications.hasAuthor(author));
      return this;
      }

      // other criterias ...

      public List<Book> find() {
      return this.bookRepository.findAll(filters);
      }
      }
      }

      As you can see i am just joining filter Criterias together, and thats it. The implementation is really simple but also expandable. These filter Criterias are supported by my BookRepository (=DAO). I just have to define them in a helper class first. Check out this and that for a deeper understanding how to combine spring-data with criteria queries.





      to the comments