파라미터 타입이 다른 공통 로직 모듈화 - 정적 팩토리 메서드
2024.12.11 - [Java] - 파라미터 타입이 다른 공통 로직 모듈화 - 인터페이스
2024.12.11 - [Java] - 파라미터 타입이 다른 공통 로직 모듈화 - 제네릭
파라미터 타입이 다른 공통 로직 모듈화 - 제네릭
파라미터 타입이 다른 공통 로직 모듈화 -2024.12.11 - [Java] - 파라미터 타입이 다른 공통 로직 모듈화 - 인터페이스 파라미터 타입이 다른 공통 로직 모듈화 - 인터페이스파라미터 타입이 달라 코
99duuk.tistory.com
다시 이어서 ..
2024.10.21 - [Java] - 정적 팩토리 메서드
정적 팩토리 메서드
| 정적 팩토리 메서드는 객체를 만드는 특별한 방법임일반적인 생성자 대신, 클래스 안에 객체를 만드는 전용 메서드를 만들어 사용함.이 메서드는 이름을 가질 수 있어서 객체가 어떤 목적으로
99duuk.tistory.com
이게 떠올라서 얘도 갖다 붙혀봄..
얘는 좀 부적절한 것 같긴 함..
정적 팩토리 메서드는 객체 생성을 캡슐화하는데 주로 사용되지만, 공통 로직을 처리하는 데 사용될 수도 있음..
적절한 구현체를 생성하거나 로직을 처리해야 하는 경우,
인터페이스와 제네릭 대신 정적 팩토리 메서드도 활용 가능
정적 팩토리 메서드를 사용하면, 공통 로직의 모듈화뿐 아니라,
다양한 객체를 생성하거나 처리하는 과정을 캡슐화할 수 있음
※ 정적 메서드란 ? 객체와 독립적으로 동작하는 클래스 기반 메서드 (특정 객체에 종속되지 않고, 클래스 이름만으로 호출 가능한 메서드)
왜 정적 메서드를 사용하는가?
- 객체 상태와 무관한 작업: 정적 메서드는 특정 객체의 상태와 관계없이 전역적으로 호출 가능한 작업을 처리하기 위해
- 유틸리티성 로직: 일반적으로, 공통 로직이나 유틸리티 작업을 수행할 때 객체를 생성하지 않고도 호출 가능한 구조를 제공
- 인스턴스 생성 비용 제거: 객체를 생성하지 않아도 동작하기 때문에 불필요한 메모리 낭비를 줄일 수 있
정적 메서드를 사용하는 이유를 명확히 하기 위해,
객체 생성과 처리 로직을 하나의 정적 메서드에 통합하거나,
정적 메서드의 유틸리티성을 강조해야 함...
예시: 동물 객체의 인증 정보 처리
문제 상황
- Dog, Cat, Bird와 같은 동물 객체가 있고, 모두 Auth를 상속
- 각 동물의 Auth 정보를 기반으로 특정한 동작(예: getAuthority)을 수행해야
- 파라미터 타입이 다르기 때문에 공통 로직 모듈화가 어려움
정적 팩토리 메서드 활용하기
- 공통 부모 클래스와 동물 클래스 정의
public abstract class Auth {
private Authority authority;
public Authority getAuthority() {
return authority;
}
public void setAuthority(Authority authority) {
this.authority = authority;
}
}
public class Dog extends Auth {
private String breed; // 고유 속성
}
public class Cat extends Auth {
private String furColor; // 고유 속성
}
public class Bird extends Auth {
private boolean canFly; // 고유 속성
}
1. 정적 팩토리 메서드 클래스 구현
AnimalAuthProcessor라는 유틸리티 클래스를 만들어, 다양한 동물 객체를 처리하는 로직을 캡슐화
public class AnimalAuthProcessor {
public static void processAuth(String animalType, Authority authority) {
Auth animal;
// 객체 생성과 로직 통합
switch (animalType.toLowerCase()) {
case "dog":
animal = new Dog();
break;
case "cat":
animal = new Cat();
break;
case "bird":
animal = new Bird();
break;
default:
throw new IllegalArgumentException("Unknown animal type: " + animalType);
}
animal.setAuthority(authority);
// 공통 로직 처리
System.out.println("Processing Auth for: " + animal.getClass().getSimpleName());
System.out.println("Authority: " + animal.getAuthority().getRole());
}
}
2. 사용 예시
정적 팩토리 메서드를 호출하여 다양한 동물 객체를 처리
public class Main {
public static void main(String[] args) {
AnimalAuthProcessor.processAuth("dog", new Authority("Dog Authority"));
AnimalAuthProcessor.processAuth("cat", new Authority("Cat Authority"));
AnimalAuthProcessor.processAuth("bird", new Authority("Bird Authority"));
}
}
이 방식의 장점:
- 객체 생성과 호출이 분리되지 않고 한 곳에서 처리됨.
- 사용자 입장에서 간결하게 사용할 수 있음.
2. 유틸리티성 강조
정적 메서드를 객체 생성과 분리하고, 이미 생성된 객체를 처리하는 공통 유틸리티 로직으로 제한
객체 생성과 처리는 각 클래스에서 담당하게 하고, 정적 메서드는 단순히 반복되는 로직만 처리하도록
public class AnimalAuthProcessor {
public static void processAuth(Auth animal) {
System.out.println("Processing Auth for: " + animal.getClass().getSimpleName());
System.out.println("Authority: " + animal.getAuthority().getRole());
}
}
사용
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.setAuthority(new Authority("Dog Authority"));
AnimalAuthProcessor.processAuth(dog);
Cat cat = new Cat();
cat.setAuthority(new Authority("Cat Authority"));
AnimalAuthProcessor.processAuth(cat);
Bird bird = new Bird();
bird.setAuthority(new Authority("Bird Authority"));
AnimalAuthProcessor.processAuth(bird);
}
}
이 방식의 장점:
- 객체 생성과 로직 처리를 명확히 분리.
- 정적 메서드는 공통 로직만 캡슐화.
정적 메서드를 쓸 이유가 없는 경우
만약 다음 조건을 충족한다면 굳이 정적 메서드를 사용할 필요는 없
- 객체 생성 이후에 호출되며, 객체 상태를 활용해야 하는 경우.
- 메서드가 객체의 고유 동작을 수행해야 할 경우.
이런 경우, 인스턴스 메서드를 활용하는 것이 더 적합
결론적으로 좀 쓸데없어 보이긴 함..
정적 메서드의 장점을 살리려면:
- 객체 생성과 호출을 통합하거나,
- 유틸리티 작업으로 범위를 한정해야..
1. 정적 팩토리 메서드 방식 vs. 인터페이스 방식
공통점
- 공통 로직 처리
- 두 방식 모두 반복되는 코드를 제거하고, 공통된 로직을 한 곳에 모으는 것이 목적
- 모듈화
- 반복적으로 사용될 로직을 별도의 클래스로 분리하여 코드의 재사용성을 높이고 유지보수를 용이하게
2. 인터페이스 방식과 정적 메서드 방식의 비교
(1) 정적 메서드 방식의 장점
- 독립적 사용 가능
- 정적 메서드는 객체 생성 없이 호출 가능하므로, 특정 클래스나 인터페이스를 강제할 필요 없이 자유롭게 사용 가능
- 예: AnimalAuthProcessor.processAuth()는 어떤 객체와도 연계되지 않은 독립적 로직임
- 간결하고 직관적인 호출
- 공통 작업을 수행하는 단순한 유틸리티 로직이라면, 정적 메서드가 더 간단하고 직관적으로 보일 수도
- 예: Math.abs(), Arrays.sort()처럼, 범용적인 작업에 적합.
- 의존성 제거
- 인터페이스 방식은 구현체를 강제하지만, 정적 메서드는 어느 클래스에도 의존하지 않으므로 호출하기 더 가벼움
(2) 인터페이스 방식의 장점
- 다형성 지원
- 인터페이스는 다형성을 제공하므로, 호출자가 구현체에 상관없이 일관된 방식으로 동작을 호출할 수 있음
- 예: List, Map처럼 다양한 구현체를 통합된 방식으로 처리.
- 확장성
- 새로운 구현체를 추가해도 기존 코드 수정 없이 인터페이스만 구현하면 공통 동작을 제공할 수 있음
- 예: Dog, Cat, Bird가 모두 Animal 인터페이스를 구현했다면, 호출자는 Animal 타입만 알면 됨
- 동작 강제
- 인터페이스는 특정 메서드(동작)를 반드시 구현하도록 강제
- 예: getAuthority() 메서드를 모든 동물 클래스에서 강제 구현.
4. 어떤 방식이 더 적합할까?
정적 메서드 방식이 적합한 경우
- 공통 로직 자체가 객체의 상태와 무관하며, 독립적으로 실행될 수 있는 경우.
- 예: 숫자 연산(Math.abs()), 데이터 변환(DateFormatter.format()), 특정 로직 처리(processAuth()).
인터페이스 방식이 적합한 경우
- 공통 동작을 강제해야 하거나, 구현체에 따라 다르게 동작해야 하는 경우.
- 예: 다양한 동물 객체의 동작(먹기, 걷기, 울기)을 공통 인터페이스로 강제하는 경우.
결론
- 정적 메서드 방식과 인터페이스 방식은 서로 대체 가능한 방법이 아니라, 목적이 다른 방법
- 정적 메서드 방식은 독립적인 공통 로직 처리와 유틸리티 작업에 적합하고, 인터페이스 방식은 다형성과 확장성, 공통 동작 강제에 적합
- 따라서, "공통 로직 처리"라는 목적은 같아도, 설계 의도에 따라 선택해야 하며, 둘 중 하나를 더 적합한 방식으로 결정할 수 있
결론적으로, 정적 메서드 방식은 더 간단한 호출을 선호하거나, 객체 상태와 독립된 공통 로직이 있을 때 더 적합하며,
인터페이스 방식은 다형성을 활용하거나, 특정 동작을 강제하려는 설계 의도가 있을 때 적합
벗..
'공통 로직 처리'라는 목적만을 고려한다면, 일반적으로 인터페이스 방식이 더 적합할듯...