-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
🐳 02 Objects2장 객체 생성과 파괴2장 객체 생성과 파괴🙇🏻 help wanted맡은 주제를 잘 모르겠어요. 도움이 필요해요.맡은 주제를 잘 모르겠어요. 도움이 필요해요.
Description
Chapter : 2. 객체 생성과 파괴
Item : 1. 생성자 대신 정적 팩터리 메서드를 고려하라.
Assignee : byunghyunkim0
🍑 서론
클래스는 클라이언트에 public 생성자 대신 정적 팩토리 메서드를 제공할 수 있다.
- 간단한 정적 팩토리 메서드의 예
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}🍑 본론
정적 팩토리 메서드(static factory method)
Static Method를 이용하여 인스턴스를 생성하는 방식
class Book {
private String title;
// 생성자를 private화 하여 외부에서 생성자 호출 차단
private Book(String title) { this.title = title; }
// 정적 팩토리 메서드
public static Book titleOf(String title) {
return new Book(title); // 메서드에서 생성자를 호출하고 리턴함
}
}
public static void main(String[] args) {
// 정적 메서드 호출을 통해 인스턴스화된 객체를 얻음
Book book1 = Book.titleOf("어린왕자");
}정적 팩토리 메서드의 장점 (5가지)
1. 이름을 가질 수 있다.
- 생성자에 넘기는 매개변수만으로 반환되는 객체의 특성을 알기 어렵다.
- 적적한 이름의 정적 메서드를 사용하면 반환될 객체의 특성을 묘사할 수 있다.
class Car {
private String brand;
private String color = "black";
public Car(String brand, String color) {
this.brand = brand;
this.color = color;
}
public Car(String brand) {
this.brand = brand;
}
}
public static void main(String[] args) {
// 검정색 테슬라 자동차
Car teslaCar = new Car("Tesla");
// 빨간색 BMW 자동차
Car bmwRedCar = new Car("BMW", "Red");
}class Car {
private String brand;
private String color;
// private 생성자
private Car(String brand, String color) {
this.brand = brand;
this.color = color;
}
// 정적 팩토리 메서드 (매개변수 하나는 from 네이밍)
public static Car brandBlackFrom(String brand) {
return new Car(brand, "black");
}
// 정적 팩토리 메서드 (매개변수 여러개는 of 네이밍)
public static Car brandColorOf(String brand, String color) {
return new Car(brand, color);
}
}
public static void main(String[] args) {
// 검정색 테슬라 자동차
Car teslaCar = Car.brandBlackFrom("Tesla");
// 빨간색 BMW 자동차
Car bmwRedCar = Car.brandColorOf("BMW", "Red");
}2. 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
메서드를 통해 간접적으로 객체를 생성하기 때문에, 전반적인 객체 생성 및 통제 관리를 할 수 있다. 필요에 따라서 새로운 객체를 생성할수도 있고, 객체 하나만 만들어두고 이를 공유하여 재사용하게 하여 불필요한 객체 생성을 방지 할 수 있다.
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// 이미 등록된 요일 가져오기
Day day = DayFactory.from("Monday");
System.out.println(day.getDay());
// 등록되지 않은 요일 가져오기
day = DayFactory.from("Friday");
System.out.println(day.getDay());
}
}
class Day {
private String day;
public Day(String day) { this.day = day; }
public String getDay() { return day; }
}
// Day 객체를 생성하고 관리하는 Flyweight 팩토리 클래스
class DayFactory {
// Day 객체를 저장하는 캐싱 저장소 역할
private static final Map<String, Day> cache = new HashMap<>();
// 자주 사용될것 같은 Day 객체 몇가지를 미리 등록한다
static {
cache.put("Monday", new Day("Monday"));
cache.put("Tuesday", new Day("Tuesday"));
cache.put("Wednesday", new Day("Wednesday"));
}
// 정적 팩토리 메서드 (인스턴스에 대해 철저한 관리)
public static Day from(String day) {
return cache.get(day);
}
}3. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
class Main{
public static void main(String[] args) {
SmarPhone s = SmarPhone.getPhone(600000);
System.out.println(s instanceof IPhone);
}
}
class Galaxy implements SmarPhone {}
class IPhone implements SmarPhone {}
class Huawei implements SmarPhone {}
interface SmarPhone {
public static SmarPhone getPhone(int price) {
if(price > 100000) {
return new IPhone();
}
if(price > 50000) {
return new Galaxy();
}
return new Huawei();
}
}5. 정적 팩토리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
- 어떤 타입의 객체를 반환할지 결정하는 로직이 팩토리 메서드 내부에 있기 때문에 클라이언트는 팩토리 메서드를 호출하기만 하면 되고, 클라이언트는 어떤 클래스의 객체가 생성되는지 알 필요가 없다.
- 새로운 타입의 객체가 필요해진다면 팩토리 메서드만 수정하면 된다.
- 유연한 확장성을 가질 수 있고, 내부 구현을 드러내지 않아 캡슐화할 수 있다는 장점도 있다.
public class CarFactory {
private CarFactory() {
}
public static Car createCar(String type) {
if (type.equals("sports")) {
return new SportsCar();
}
if (type.equals("suv")) {
return new SuvCar();
}
throw new IllegalArgumentException("해당 타입의 자동차가 존재하지 않습니다 : " + type);
}
}정적 팩토리 메서드의 단점 (2가지)
1. 상속을 하려면 public이나 protected 생성자가 필요하니 정적 팩토리 메서드만 제공하면 하위 클래스를 만들 수 없다.
- 생성자가 private이기 때문에 상속이 불가능하다.
- "상속 보단 합성" 원칙에 따라서 상속보다는 합성을 사용하는 것을 권한다.
2. 정적 팩토리 메서드는 프로그래머가 찾기 어렵다.
🍑 결론
Referenced by
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
🐳 02 Objects2장 객체 생성과 파괴2장 객체 생성과 파괴🙇🏻 help wanted맡은 주제를 잘 모르겠어요. 도움이 필요해요.맡은 주제를 잘 모르겠어요. 도움이 필요해요.