생성자로 인스턴스를 생성하고 싶지 않을 때
- new 키워드로 객체를 생성하면 클래스의 이름이 노출됨 (되면 안되나?)
- Employee employee = new Employee();
- 생성되는 클래스의 이름을 숨기거나, 상황에 따라 인스턴스의 생성이 가능하도록 하고자 할 때
- 컴파일 시간이 아닌 실행시간에 생성되는 인스턴스가 결정되어야 할 때
리팩토링과 디자인 패턴이 정답은 아니다.
이렇게 하면 좋고, 이렇게 하면 좀 더 객체지향적이고 이렇게 하면 좀 더 유지보수가 쉽다.
이 프로그램을 계속 써야 할 경우 어떻게 하면 좀 더 유연하게 만들어서 업그레이드 하는데 시간을 덜 들이는게 목적.
그러기 위하여 객체지향적으로 만들고 리팩토링을 해서 좀 더 코드를 유지보수를 쉽게 하는 것
고객 등급이 계속 늘어날 것으로 예상되면 switch case 분리하고 class 분리하는 것이 맞다.
생성할 때 유연성이 필요하면 factory method 쓰는 것이 맞다.
AS-IS
package factorymethod.before;
public class Customer {
private int customerType;
private String customerName;
private String customerGrade;
private int bonusPoint;
public static final int BRONZE_CUSTOMER = 1;
public static final int SILVER_CUSTOMER = 2;
public static final int GOLD_CUSTOMER = 3;
public Customer(int customerType, String customerName) {
this.customerType = customerType;
this.customerName = customerName;
}
public String getCustomerGrade() {
switch(customerType) {
case BRONZE_CUSTOMER: return "BRONZE";
case SILVER_CUSTOMER: return "SILVER";
case GOLD_CUSTOMER: return "GOLD";
default : return null;
}
}
public int calPrice(int price) {
switch(customerType) {
case BRONZE_CUSTOMER:
return price;
case SILVER_CUSTOMER:
price = price - (int)(price * 0.05);
return price;
case GOLD_CUSTOMER:
price = price - (int)(price * 0.1);
return price;
default : return price;
}
}
public int calBonusPoint(int price) {
switch(customerType) {
case BRONZE_CUSTOMER:
return bonusPoint += (price * 0.01);
case SILVER_CUSTOMER:
return bonusPoint += (price * 0.05);
case GOLD_CUSTOMER:
return bonusPoint += (price * 0.1);
default : return price;
}
}
public String getCustomerName() {
return customerName;
}
public String toString() {
return customerName + "님의 멤버십 등급은 " + getCustomerGrade() + "입니다.";
}
}
package factorymethod.before;
public class Main {
public static void main(String[] args) {
Customer bronzeCustomer = new Customer(Customer.BRONZE_CUSTOMER, "Tomas");
Customer silverCustomer = new Customer(Customer.SILVER_CUSTOMER, "Alice");
Customer goldCustomer = new Customer(Customer.GOLD_CUSTOMER, "Edward");
int price = 10000;
System.out.println(bronzeCustomer);
System.out.println(bronzeCustomer.getCustomerName() + ": price : " + bronzeCustomer.calPrice(price)
+ " bonusPoint: " + bronzeCustomer.calBonusPoint(price));
System.out.println(silverCustomer);
System.out.println(silverCustomer.getCustomerName() + ": price : " + silverCustomer.calPrice(price)
+ " bonusPoint: " + silverCustomer.calBonusPoint(price));
System.out.println(goldCustomer);
System.out.println(goldCustomer.getCustomerName() + ": price : " + goldCustomer.calPrice(price)
+ " bonusPoint: " + goldCustomer.calBonusPoint(price));
}
}
TO-BE
package factorymethod.after;
public class Customer {
private int customerType;
private String customerName;
private String customerGrade;
private int bonusPoint;
public static final int BRONZE_CUSTOMER = 1;
public static final int SILVER_CUSTOMER = 2;
public static final int GOLD_CUSTOMER = 3;
private Customer(int customerType, String customerName) {
this.customerType = customerType;
this.customerName = customerName;
}
public static Customer create (int customerType, String customerName) {
return new Customer(customerType, customerName);
}
public String getCustomerGrade() {
switch(customerType) {
case BRONZE_CUSTOMER: return "BRONZE";
case SILVER_CUSTOMER: return "SILVER";
case GOLD_CUSTOMER: return "GOLD";
default : return null;
}
}
public int calPrice(int price) {
switch(customerType) {
case BRONZE_CUSTOMER:
return price;
case SILVER_CUSTOMER:
price = price - (int)(price * 0.05);
return price;
case GOLD_CUSTOMER:
price = price - (int)(price * 0.1);
return price;
default : return price;
}
}
public int calBonusPoint(int price) {
switch(customerType) {
case BRONZE_CUSTOMER:
return bonusPoint += (price * 0.01);
case SILVER_CUSTOMER:
return bonusPoint += (price * 0.05);
case GOLD_CUSTOMER:
return bonusPoint += (price * 0.1);
default : return price;
}
}
public String getCustomerName() {
return customerName;
}
public String toString() {
return customerName + "님의 멤버십 등급은 " + getCustomerGrade() + "입니다.";
}
}
package factorymethod.after;
public class Main {
public static void main(String[] args) {
Customer bronzeCustomer = Customer.create(Customer.BRONZE_CUSTOMER, "Tomas");
Customer silverCustomer = Customer.create(Customer.SILVER_CUSTOMER, "Alice");
Customer goldCustomer = Customer.create(Customer.GOLD_CUSTOMER, "Edward");
int price = 10000;
System.out.println(bronzeCustomer);
System.out.println(bronzeCustomer.getCustomerName() + ": price : " + bronzeCustomer.calPrice(price)
+ " bonusPoint: " + bronzeCustomer.calBonusPoint(price));
System.out.println(silverCustomer);
System.out.println(silverCustomer.getCustomerName() + ": price : " + silverCustomer.calPrice(price)
+ " bonusPoint: " + silverCustomer.calBonusPoint(price));
System.out.println(goldCustomer);
System.out.println(goldCustomer.getCustomerName() + ": price : " + goldCustomer.calPrice(price)
+ " bonusPoint: " + goldCustomer.calBonusPoint(price));
}
}
TO-BE 2
package factorymethod.after2;
public class BronzeCustomer extends Customer {
private BronzeCustomer(String customerName) {
super(customerName);
// TODO Auto-generated constructor stub
}
public static BronzeCustomer create(String customerName) {
return new BronzeCustomer(customerName);
}
public String getCustomerGrade() {
return "BRONZE";
}
public int calPrice(int price) {
return price;
}
public int calBonusPoint(int price) {
return bonusPoint += (price * 0.01);
}
}
package factorymethod.after2;
public class GoldCustomer extends Customer {
private GoldCustomer(String customerName) {
super(customerName);
// TODO Auto-generated constructor stub
}
public static GoldCustomer create(String customerName) {
return new GoldCustomer(customerName);
}
public String getCustomerGrade() {
return "GOLD";
}
public int calPrice(int price) {
return price - (int)(price * 0.1);
}
public int calBonusPoint(int price) {
return bonusPoint += (price * 0.1);
}
}
package factorymethod.after2;
public abstract class Customer {
protected String customerName;
protected String customerGrade;
protected int bonusPoint;
Customer(String customerName){
this.customerName = customerName;
}
public abstract String getCustomerGrade();
public abstract int calPrice(int price);
public abstract int calBonusPoint(int price);
public String getCustomerName() {
return customerName;
}
public String toString() {
return customerName + "님의 멤버십 등급은 " + getCustomerGrade() + "입니다.";
}
}
package factorymethod.after2;
public class Main {
public static void main(String[] args) {
Customer bronzeCustomer = BronzeCustomer.create("Tomas");
Customer silverCustomer = SilverCustomer.create("Alice");
Customer goldCustomer = GoldCustomer.create("Edward");
int price = 10000;
System.out.println(bronzeCustomer);
System.out.println(bronzeCustomer.getCustomerName() + ": price : " + bronzeCustomer.calPrice(price)
+ " bonusPoint: " + bronzeCustomer.calBonusPoint(price));
System.out.println(silverCustomer);
System.out.println(silverCustomer.getCustomerName() + ": price : " + silverCustomer.calPrice(price)
+ " bonusPoint: " + silverCustomer.calBonusPoint(price));
System.out.println(goldCustomer);
System.out.println(goldCustomer.getCustomerName() + ": price : " + goldCustomer.calPrice(price)
+ " bonusPoint: " + goldCustomer.calBonusPoint(price));
}
}
'java > java 리팩토링' 카테고리의 다른 글
08. 상속을 위임으로 바꾸기 (0) | 2023.02.12 |
---|---|
07. 전략, 상태패턴 적용하기 (0) | 2023.02.11 |
05. if-else, if-switch 문의 분류 코드를 하위 클래스로 만들기 (0) | 2023.02.08 |
04. 분류 코드를 클래스로 만들기 (0) | 2023.02.08 |
03. null 객체 사용 (0) | 2023.02.07 |
댓글