Handle business logic for a set of Entity in Java class

Handle business logic for a set of Entity in Java class

Introduction

The logic for a single Entity should define the behavior for the Entity, but I'm confused about where to write the processing for the list or set of Entity. I have summarized the contents that I investigated to solve such a hesitation.

Common programs

I often write processing for lists and sets of Entity in Service and Controller.

HogeController.java


@Controller
public class HogeController {
  private final HogeService service;

  HogeController(HogeService service) {
   this.service = service;
  }  

  @RequestMapping("hoge")
  public String xxx(Model model) {
    List<ShoppingCartItem> cartItems = new ArrayList<>();
    Integer total = cartItems.stream().mapToInt(ShoppingCartItem::subtotal()).sum();
    model.addAttribute("total", total);
    return "hoge/hoge";
  }
}

I think this is fine. However, if you write the process in the Controller, when you want to perform the same process in another Controller, the code will probably be copied and maintenance will be difficult when the logic is changed. Is visible.

Create a class that represents a set

Therefore, if you create a class that represents a set as shown below, you can confine the logic in one place.

ShoppingCartItems.java


public class ShoppingCartItems {
  private List<ShoppingCartItem> items = new ArrayList<>();
  public void addItem(ShoppingCartItem item) {
    items.add(item);
  }
  public Integer total() {
     return items.stream().mapToInt(ShoppingCartItem::subtotal()).sum();
 }
}

Now you've locked the method for calculating the total amount into one class. However, this is still inconvenient. This is because you cannot retrieve each ShoppingCartItem. ~~ Brain death ~~ It's okay to define Getter, but here are some useful techniques.

Allow extended for statements to be used even if they are not Lists

There is an extended for statement as the syntax that you will use to retrieve each ShoppingCartItem. It would be nice if you could call it like this!

ShoppingCartItems shoppingCartItems = new ShoppingCartItems();
for (ShoppingCardItem item : shoppingCartItems) {
  // doSomething
}

To achieve this, it is better to implement the ʻIterable ` interface.

ShoppingCartItems.java


public class ShoppingCartItems implements Iterable<ShoppingCartItem> {
  private List<ShoppingCartItem> items = new ArrayList<>();
  //abridgement
  @Override
  public Iterator<Asking> iterator() {
    return items.iterator();
  }

  @Override
  public void forEach(Consumer<? super Asking> action) {
    items.forEach(action);
  }

  @Override
  public Spliterator<Asking> spliterator() {
    return items.spliterator();
  }
}

For the three methods that should be implemented in the Iterable interface, you can call the method of the collection class ʻitems` field held in the class. Now you can write an extended for statement.

I also want to use it in the JSTL forEach tag

I want to write like this.

HogeController.java


@Controller
public class HogeController {
  @GetMapping("hoge")
  public String hoge(Model model) {
    model.addAttribute("shoppingCartItems", new ShoppingCartItems());
    return "hoge";
  }
}

hoge.jsp


<c:forEach items="${shoppingCartItems}" var="shoppingCartItem">
<%-- do something --%>
</c:forEach>

In conclusion, without using JSTL ,. Only the following variables can be set to the items attribute in the JSTL forEach tag.

This limit is quite strict. Since I am dealing with lists this time, I think that I will implement the Collection type, but I personally wanted to avoid the Collection type because there are many unnecessary methods. So this time I implemented the Iterator type on the assumption that the loop is rotated only once.

ShoppingCartItems.java


public class ShoppingCartItems implements Iterable<ShoppingCartItem>, Iterator<ShoppingCartItem> {
  private List<ShoppingCartItem> items = new ArrayList<>();
  //abridgement
  private int cursor = 0;
 
  @Override
  public boolean hasNext() {
    if (cursor < items.size()) {
      return true;
    }
    return false;
  }

  @Override
  public ShoppingCartItem next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    return items.get(cursor++); //If you do not increment it, it will loop infinitely ☆ 彡
  }
}

You can now specify an instance of the ShoppingCartItems class in the items attribute of the JSTL forEach tag.

I want to use Stream API

You can use it by defining the items field stream method as a delegation method to this ShoppingCartItems. If you have other methods you need, you can define a delegation method in this class and it will be ready to use. However, we do not recommend defining methods that perform unnecessary operations in your business logic.

ShoppingCartItems.java


public Stream<ShoppingCartItem> stream() {
  return items.stream();
}

In the first place, the purpose of creating a class for handling collections is to prevent tampering with collections and to increase cohesion. If you define too many methods, it will not serve your purpose. Before you define a method, make sure you really need it.

at the end

I think it's common to write operations on sets, especially operations related to business logic, in the Service class. In the future, I would like to consider defining a class that has a set as a field as a means to confine the business logic for the set in one place.

Recommended Posts

Handle business logic for a set of Entity in Java class
A quick review of Java learned in class
A quick review of Java learned in class part3
A quick review of Java learned in class part2
What is a class in Java language (3 /?)
What is a class in Java language (1 /?)
What is a class in Java language (2 /?)
Creating a matrix class in Java Part 1
Measure the size of a folder in Java
A collection of simple questions for Java beginners
Set pop-up display for Java language in vim.
Cause of is not visible when calling a method of another class in java
Write a class that can be ordered in Java
Browse class objects in Kotlin (instead of Java class name.class)
Write a class in Kotlin and call it in Java
A note for Initializing Fields in the Java tutorial
[Ruby / Rails] Set a unique (unique) value in the class
Use of Abstract Class and Interface properly in Java
Summarize the additional elements of the Optional class in Java 9
A brief explanation of a maze game made in Java for a cousin of an elementary school student
[For beginners] Explanation of classes, instances, and statics in Java
A quick explanation of the five types of static in Java
[Java] Set structure of collection class (about HashSet and TreeSet)
Activate Excel file A1 cell of each sheet in Java
[MQTT / Java] Implemented a class that does MQTT Pub / Sub in Java
I investigated Randoop, a JUnit test class generator for Java
I tried to make a client of RESAS-API in Java
[Java] Comparator of Collection class
Find a subset in Java
[Java] Summary of for statements
Summary of Java Math class
Implementation of gzip in java
Implementation of tri-tree in Java
Let's create a TODO application in Java 4 Implementation of posting function
I can't create a Java class with a specific name in IntelliJ
Let's create a TODO application in Java 6 Implementation of search function
Let's create a TODO application in Java 8 Implementation of editing function
Mechanism and characteristics of Collection implementation class often used in Java
The milliseconds to set in /lib/calendars.properties of Java jre is UTC
Cast an array of Strings to a List of Integers in Java
Examine the list of timezone IDs available in the Java ZoneId class
Get the public URL of a private Flickr file in Java
Creating a matrix class in Java Part 2-About matrices (linear algebra)-
Let's create a TODO application in Java 1 Brief explanation of MVC
[Java] Returns a Japanese name file in filename of HTTP header
Let's create a TODO application in Java 5 Switch the display of TODO
How to think about class design (division) in a business system (1)
How to check for the contents of a java fixed-length string
Achieve exclusive control of datasets in a multithreaded Java environment (WAS for z / OS environment) on IBM mainframes
Think of a Java update strategy
Various methods of Java String class
3 Implement a simple interpreter in Java
[Java] Memo for naming class names
I created a PDF in Java.
A list of rawValues for UITextContentType.
Sort a List of Java objects
Handle your own annotations in Java
StringBuffer and StringBuilder Class in Java
java (use class type for field)
A simple sample callback in Java
List of members added in Java 9