Favor Skeletal Implementation in Java
Interface와 Abstract Class의 장점을 모두 취하는 방법인 Skeletal Implementation을 구현해보자
인터페이스를 통해 구현체에게 필요한 메서드를 강제하고,
구현체에 공통된 메서드는 추상클래스가 상속받도록 해서 불필요한 코드의 중복은 줄이자
구현체에게 필요한 메서드를 명시한 인터페이스 뼈대를 만든다
public interface Invending {
void start();
void chooseProduct();
void stop();
void process();
}
인터페이스의 구현체로서 공통되는 구현을 정의하는 추상 클래스 만들기
public abstract class AbstractVending implements Invending{
@Override
public void start() {
System.out.println("Start Vending Machine");
}
@Override
public void stop() {
System.out.println("Stop Vending Machine");
}
@Override
public void process() {
start();
chooseProduct();
stop();
}
}
서브 클래스를 작성하고 그 안에 추상 클래스를 상속받는 위임자 클래스를 만든다
그리고 위임자 클래스는 호출을 AbstractVending으로 전달함
공통되지 않아서 위 추상 클래스에서 구현하지 않은 chooseProduct 구현
public class CandyVending implements Invending{
AbstractVendingDelegator delegator = new AbstractVendingDelegator();
@Override
public void start() {
delegator.start();
}
@Override
public void chooseProduct() {
delegator.chooseProduct();
}
@Override
public void stop() {
delegator.stop();
}
@Override
public void process() {
delegator.process();
}
private class AbstractVendingDelegator extends AbstractVending{
@Override
public void chooseProduct() {
System.out.println("Produce diiferent candies");
System.out.println("Choose a type of candy");
System.out.println("pay for candy");
System.out.println("collect candy");
}
}
}
public class DrinkVending implements Invending{
AbstractVendingDelegator delegator = new AbstractVendingDelegator();
@Override
public void start() {
delegator.start();
}
@Override
public void chooseProduct() {
delegator.chooseProduct();
}
@Override
public void stop() {
delegator.stop();
}
@Override
public void process() {
delegator.process();
}
private class AbstractVendingDelegator extends AbstractVending{
@Override
public void chooseProduct() {
System.out.println("Produce diiferent soft drinks");
System.out.println("Choose a type of soft drinks");
System.out.println("pay for drinks");
System.out.println("collect drinks");
}
}
}
인터페이스 동일한 메서드가 있는 경우, 항상 추상 클래스를 생성하자