Java Design and Coding

Last modified 22 Apr 2021 17:31 +02:00

Java Design and Coding

Formatting and Naming Conventions Synopsis

Indent: 4 spaces

/*
 * Copyright (c) 2010-2019 Evolveum and contributors
 *
 * This work is dual-licensed under the Apache License 2.0
 * and European Union Public License. See LICENSE file for details.
 */
package com.evolveum.midpoint.provisioning.impl;

import ...

/**
 * This is class JavaDoc (if needed).
 *
 * @author Radovan Semancik
 */
public class ClassName {
    private static final String THIS_IS_CONSTANT = "foo";

    private static final Trace LOGGER = TraceManager.getTrace(ClassName.class);

    @Autowired private PrismContext prismContext;

    private List<String> someStrings;

    public ClassName() {
        super();
    }

    /**
     * Short method JavaDoc (if needed at all).
     */
    private void methodName(final String paramName, Object[] someThings) {
        long localVar = 42L;
        final String localFinal = "foo" + "bar";

        if (THIS_IS_CONSTANT.equals(paramName)) {
            // Braces are needed for multi-line if-then-else
            // Must not have empty blocks. Except if there is a comment explaining why the block is empty.

        } else if (localFinal.equals(paramName)) {
            // else if may be simplified like this

        } else {
            throw new IllegalArgumentException("Unexpected input '" + paramName + "'");
        }

        // Single-line if statements may be without braces
        if (someStrings.isEmpty()) return;

        // TODO: MID-1234
        throw new UnsupportedOperationException("Not implemented yet (MID-1234)");
    }
}

Class and Interface Names

  • Use UpperCamelCase

  • Do not use "I" prefix for interface names. Use just plain, simple and relatively short names for interfaces. The user of the interface should not care whether he is using abstract class or interface (he should not create it using constructors anyway). Therefore use User, notIUser.

  • It is not required to use able suffix for interfaces, but it helps in some cases. User is a perfectly good name for an interface as Userable, Userish or Userlike are quite queer. However, Readable is preferred to Read, Reading or other strange forms.

  • Class names that implement interfaces should somehow be related to the interface that they implement (or the most important interface in case of implementing multiple interfaces). For example class implementing interface User could be UserImpl, UserMock, UserDbImpl or DbBasedUser (although the last one is not ideal).

  • Keep interfaces, abstract classes and other entities that form cross-component interface in a separate "API" Java package. See below for naming conventions.

Getters and Setters

  • Getter and setter methods should be used only for simple properties. The invocation of getter and setter methods should not fail. Getter and setter methods should not block on a network condition (or any other condition external to the system).

  • Getter and setter methods should not throw checked exceptions, and they should not throw any exception at all if possible. They in fact may throw runtime exception, but expect that the system will fail in a spectacular way if that happens.

  • If you need accessor or mutator methods that could fail, give them a different name. For example retrieveFoo instead of getFoo or registerBar instead of setBar.

Best Practice

  • code against interfaces, not base implementation nor other implementation classes. For example define local variable as Map map; not HashMap map;

Source Code Structure and Build

Package Names

  • Use com.evolveum.midpoint prefix for package names

  • Prefix should be followed by component name, e.g. com.evolveum.midpoint.provisioning

  • Complex components may have sub-packages, e.g. or com.evolveum.midpoint.gui.admin

  • Last segment of the package name (after component name) is used to distinguish public and private parts of the component. Public interfaces must be placed in a separate packages. In that case the implementation should be placed in a separate package as well. E.g. com.evolveum.midpoint.service package contains public service definition, com.evolveum.midpoint.service.impl contains service implementation, com.evolveum.midpoint.service.mock contains mock implementation of the service. Recommended values are provided in the following table.

Package suffix Meaning Comment

api

Public interface (that is exposed outside of component)

impl

Primary component implementation

If there are more than one implementation intended for production use, do not use this suffix. Use something that describes the implementation.

spi

Public interface intended for functionality providers

mock

Mock implementation for testing purposes

test

Special testing classes (e.g. testing utils)

Unit tests are usually using the same package name as the tested component. This allows access to package-private methods.

web

Web application sources and resources

Artifact Names

  • Use dashed name notation for artifact names name-artifacts-like-this

  • Last segment of the artifact name denotes artifact type according to following table, e.g. midpoint-repository-api, midpoint-web

Artifact Suffix Meaning Example

api

Interface, API targeted at application developers

Service API

spi

Interface, SPI targeted at functionality providers

SPI for drivers, plug-ins

impl

Implementation, implements API or SPI

web

Web application or static web page resources

midPoint web application

service

Externally available service, may also include implicit interface definition (such as generated WSDL). Also includes SOAP and REST web services. That means that this may be a separate web application or a library that is included in a web application. (maybe we should clarify that later)

Web Service