I'm sorry for the catchy or fishing title m (_ _;) m In short, I will explain how to use the Template Method pattern practically. It is difficult to spread the coding standard to all the development members. I wonder if there are many things that go wrong, such as lack of time and code reviews being messed up, skill levels being different, and so on. Therefore, when multiple business logics are shared and created by several people, let's think about the underlying class that forces the implementation to adhere to the coding standards.
--Java: JDK1.5 or later
Enforce the method name and argument / return value to be implemented The only rule, "Must inherit this class", enforces the method name and its role of each business logic class. The point is the Template Method pattern.
The structure of the class is as follows. DTO class: FooInfoDto.java, BarInfoDto.java ビジネスロジック親クラス:Proces.java Business logic class (implementation sharing part): ProcesHoge01.java, ProcesHoge02.java メインクラス(ビジネスロジック呼出し部分):Main.java
DTO "FooInfoDto" of the class (INPUT) that holds the value before processing, Create a DTO "BarInfoDto" for the class (OUTPUT) that holds the processed values. Since it is the same field, both INPUT and OUTPUT can be the same DTO, but it is easier to maintain if it is clearly separated which value is retained before and after processing. It's redundant, but it's separated.
FooInfoDto.java
package dto;
public class FooInfoDto {
private Integer id = null;
private String value = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
BarInfoDto.java
package dto;
public class BarInfoDto {
private Integer id = null;
private String value = null;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Since the method name and its role can be enforced only by the rule that "each business logic inherits and implements this parent class", it is easy to understand "what class is doing what processing?" Become. The reason for making an abstract class instead of an interface is to implement only a part of the processing part in each business logic, and to aggregate the common part in this parent class.
Proces.java
package businesslogic;
import java.util.List;
import dto.BarInfoDto;
import dto.FooInfoDto;
public abstract class Proces {
protected abstract String getProcesName();
protected abstract void proces(List<FooInfoDto> input , List<BarInfoDto> output);
public void execute(List<FooInfoDto> in, List<BarInfoDto> out) {
System.out.println( getProcesName() + "Start processing." );
proces(in, out);
System.out.println( getProcesName() + "Processing is completed." );
}
}
The "getProcesName method" gives the role of "returning a descriptive name to indicate what the class does". By setting the qualifier to "protected", you can prevent it from being called by classes outside the package.
"Proces method" is an abstract method of "to implement the actual processing contents of business logic". Again, the qualifier is set to "protected" so that it cannot be called by classes outside the package.
The "execute method" is the only method that can be called from the user side, that is, the main class (class outside the businesslogic package). Here you can enforce hook processing, processing order, etc.
The part that the members actually implement.
ProcesHoge01.java
package businesslogic;
import java.util.List;
import dto.BarInfoDto;
import dto.FooInfoDto;
public class ProcesHoge01 extends Proces {
@Override
protected String getProcesName() {
return "Hoge01 processing";
}
@Override
protected void proces(List<FooInfoDto> input, List<BarInfoDto> output) {
//Actual Hoge processing content
int index = 0;
for( FooInfoDto dto : input ) {
Integer tmpId = dto.getId()*10;
output.get(index).setId(tmpId);
String tmpValue = dto.getValue()+"_Hoge01";
output.get(index).setValue(tmpValue);
index++;
}
}
}
ProcesHoge02.java
package businesslogic;
import java.util.List;
import dto.BarInfoDto;
import dto.FooInfoDto;
public class ProcesHoge02 extends Proces {
@Override
protected String getProcesName() {
return "Hoge02 processing";
}
@Override
protected void proces(List<FooInfoDto> input, List<BarInfoDto> output) {
//Actual Hoge processing content
int index = 0;
for( FooInfoDto dto : input ) {
Integer tmpId = dto.getId() + output.get(index).getId();
output.get(index).setId(tmpId);
String tmpValue = dto.getValue()+"_Hoge02";
output.get(index).setValue(tmpValue);
index++;
}
}
}
Actually, it is the part that corresponds to the controller class. Here, it is implemented as a class that is easy to understand and is simply executed by the main method. I've left the packages as default, but it would be nice if they could be separated from the packages of the business logic classes.
Main.java
import java.util.ArrayList;
import java.util.List;
import businesslogic.ProcesHoge01;
import businesslogic.ProcesHoge02;
import dto.BarInfoDto;
import dto.FooInfoDto;
public class Main {
public static void main(String[] args) {
//DTO list to store processing results
List<BarInfoDto> out = new ArrayList<BarInfoDto>();
//Prepare the input DTO list to be processed
List<FooInfoDto> in = new ArrayList<FooInfoDto>();
for(int i=1 ; i<4 ; i++){
FooInfoDto dto = new FooInfoDto();
dto.setId(i);
dto.setValue(i+"Second value");
//Set to the input DTO list to be processed
in.add(dto);
//Set an empty DTO object in the DTO list that stores the processing result
out.add(new BarInfoDto());
}
new ProcesHoge01().execute(in, out);
//Result display
for(BarInfoDto dto : out) {
System.out.println( "-------------------------------" );
System.out.println( "ID after processing> " + dto.getId() );
System.out.println( "Value after processing> " + dto.getValue() );
}
new ProcesHoge02().execute(in, out);
//Result display
for(BarInfoDto dto : out) {
System.out.println( "-------------------------------" );
System.out.println( "ID after processing> " + dto.getId() );
System.out.println( "Value after processing> " + dto.getValue() );
}
}
}
that's all.
How was it? We would appreciate it if you could give us your opinions and advice. m (_ _) m
I think you can make the main class a Facade class with a Facade pattern to further improve readability.
Recommended Posts