01. Constructor 대신 Static Factory Method를 고려하라
public class Laptop{
private String model;
private String company;
}
public static Labtop of modelNameAndCompany(
String model, String company){
Laptop laptop = new Laptop();
laptop.company = company;
laptop.modelName = modelName;
return laptop;
}
장점
1. 이름을 가질 수 있다.
2. 간다하고 명확하게 사용할 수 있다.
3. 인스턴스를 매번 생성할 필요는 없다.
Flyweight pattern = Collection Object
Singleton pattern = Single Object
단점
1. Static Factory method만 제공하면 Constructor가 없을 수 있어 상속받은 Class를 만들 수 없다.
2. 프로그래머에게 인지가 잘 되지 않을 수 있다.
02. 많은 parameter가 있는 Constructor은 Builder를 고려하라
public static Facts{
private final int ...
private final int ...
private final int ...
private final int ...
private final int ...
}
Lombok을 통하면 훨씬 더 간단해 질 수 있다.
@Data
@Builder
public class Facts{
private final int size;
private final int serving;
@Builder.Default
private final int ...
@Builder.Default
private final int ...
@Builder.Default
private final int ...
public static FactsBuilder builder(int size int serving
return Builde()
.size(size)
.serving(serving);
}
}
장점
1. 상속받은 Class의 Builder가 정의한 build 메서드가 상위 메서드의 타입을 return 하는 것이 아닌 자신의 타입을 return 한다.
단점
1. Builder를 항상 만들어야 하기 때문에 생성 비용이 무조건 생긴다.
2. 점층적 생성자 패턴 (Argument 를 여러 개 가진 Constructor) 보다 장황하여 적은 갯수의 Parameter일 경우 오히려 좋지 않을 수 있다.
03. private contructor 나 enum Type으로 Singleton임을 보증하라
대표적인 Singleton Pattern
public static member
public class Speaker{
public static final Speaker INSTANCE = new Speaker();
private Speaker(){}
}
static factory
public class Speaker{
private static Speaker instance;
private Speaker(){}
public static synchronized Speaker getInstance(){
if (instance == null){
instatnce = new Speaker();
}
return instance;
}
}
Enum Type
public enum Speaker{
INSTANCE;
private String message;
public Speaker getInstance(){
return INSTANCE;
}
public void setMessage(String message){
this.message = message;
}
}
04. Resource를 직접 명시하지 말고, Dependency Injection을 사용하라
@Configuration
public class Config{
private static final String address = "서울시 강남구"; (X)
@Value("${base.address}")
Private String address; (O)
}
base:
address: '서울시 강남구'
Constructor Injection 의 경우 Test, flexibility를 높일 수 있다.
public class Checker{
private final String pattern;
public Checker(String pattern){
this.pattern = pattern;
}
public boolean isValid(Stirng phone){
...
}
}