IntelliJ Templates: Java Design Patterns

Reading Time: 4 minutes

The power of Java Design Patterns stems from their wide applicability. It is precisely this wide applicability which makes design patterns the perfect use case for File Templates. By leveraging IntelliJ’s File Templates, you can quickly and accurately implement these patterns without leaving your IDE.

In this blog, we will explore how to best make use of these IntelliJ Templates with Java Design Patterns. If you just want quick access to several templates which have already been created, then there is a plugin available that may interest you. If you want finer control over not only which patterns are available, but also the implementation of those patterns, then we recommend creating your own file templates.

Method 1: Using a Plugin

There is currently a plugin available which offers developers the ability to immediately implement several Java Design Patterns in their code. If you are looking for a quick way to make use of design patterns, without having to do any additional work, then using this plugin may be your best bet. Moreover, this plugin will actually refactor your code to make it match the design patterns. This is in stark contrast to file templates which only implement the pattern when the file is first created. Both approaches have their merits. Do you want to refactor existing code to use design patterns, or are you more interested in developing a new project?

The only real downsides here are that 1) not all design patterns are available via this plugin and 2) as is the nature of plugins, it is a bit of a black-box. Furthermore, if you wish to customize the templates that you are using to better suit your needs, then this may not be the method for you.

  • Pros
    • Easy to use
    • Actively maintained
    • Refactors your code
  • Cons
    • Limited selection of Design Patterns (as of April 2020)
    • Limited customization

Method 2: Manually creating a Template

If any of the design patterns in which you are interested are not available via the above plugin, then check out the example below to learn how to create your own templates.

To begin, open IntelliJ and navigate to the File and Code Templates section (File>Settings>Editor>File and Code Templates).

Create a new template by selecting the Files Tab and clicking the +.

Click the + to create a new File Template

Paste the below code into the editor and Name your new template.

package ${PACKAGE_NAME};

public class ${NAME} {

    private static ${NAME} ${NAME}Instance;

    private ${NAME}() {
    }

    public static synchronized ${NAME} getInstance() {
        if (${NAME}Instance == null) {
            ${NAME}Instance = new ${NAME}();
        }
        return ${NAME}Instance;
    }
}

That’s all there is to it! Just click OK and you can immediately use your new file template to create a file.

  • Navigate to the project Window
  • right click on the directory in which you want to add the file
  • select the appropriate template to use by hovering over the ‘New’ menu option.
  • The name that you enter will be used as a variable wherever ${NAME} appears in the Template Code.

Here is the resulting file that is generated when I enter a name of ‘Singleton’ and create the file in the ‘com.knoldus.training’ package:

By adding additional variables to the code, you can develop highly versatile templates. See the appendix for an example of how to use custom variables. As an exercise, try to edit the code used to create this template to create other templates, such as a Factory Pattern Template.

Method 3: Automatically Generating a Template

Alternatively, given a working implementation of a Design Pattern, you can create a template. For example, we could develop the singleton template seen in the previous section automatically by starting out with the file we just created! To do so, simply:

  • select Tools>’Save File as Template’
  • make the appropriate edits to the code (i.e. inserting template variables such as ${NAME}).
  • save the new template.

This method is perfect if you want an easy way to reuse and adapt your existing code without having to dig for it. This is a much more elegant alternative to copy and pasting boilerplate code.

Summary

There are a number of ways to leverage IntelliJ’s templating capability in order to efficiently use Java Design Patterns. Hopefully, this guide has given you the tools you need to create your own templates for use with your development projects. While we focused on Java Design Patterns, this same method can be used in a much more general context. I have created a number of Spring Boot and MockMVC templates that have proven extremely useful, for example. See the appendix for my CRUD-Controller template code.

Appendix

This is the code I use to generate a CRUD-Controller template:

package ${PACKAGE_NAME};
import com.fasterxml.jackson.databind.JsonMappingException;
import jdk.nashorn.internal.runtime.options.Option;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping(value = "/${type}")
public class ${NAME} {
    @Autowired
    private ${Type}Repo ${type}Repo;
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public ${Type} create${Type}(@RequestBody @Valid ${Type} ${type}) {
        return ${type}Repo.save(${type});
    }
    @GetMapping
    public List<${Type}> getAll${Type}s() {
        return ${type}Repo.findAll();
    }
    @PutMapping
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void update${Type}(@RequestBody @Valid ${Type} ${type}) {
        ${type}Repo.save(${type});
    }
    @GetMapping(value = "/{id}")
    public ${Type} get${Type}ById(@PathVariable int id) throws JsonMappingException {
         Optional<${Type}> ${type}= ${type}Repo.findById(id);
         if(${type}.isPresent())
         {return ${type}.get();}
         else{
             throw new NotFoundException("Did not find an ${type} with id "+id);
         }
    }
    @DeleteMapping(value = "/{id}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete${Type}ById(@PathVariable int id) throws JsonMappingException {
        Optional<${Type}> ${type}= ${type}Repo.findById(id);
        if(${type}.isPresent())
        {${type}Repo.deleteById(id);}
        else{
            throw new NotFoundException("Did not find an ${type} with id "+id);
        }
    }
}

As a useful exercise, try to figure out what arguments you would pass for the ${Type} and ${type} variables.

Hint: Developer developer=new Developer();

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading