✌️
Studylog
See More
Studylog
Studylog
  • INTRO
  • AWS
    • AWS101
      • Virtualization and the AWS structures
      • AWS account and free-tier
      • AWS IAM
      • AWS EC2
        • EC2 basic
        • ENI and EIP
        • Elastic Block Storage
        • Auto Scaling
        • Elastic Load Balancer
  • IaC
    • Terraform
      • License Change
      • Tutorial
      • Module
      • Versioning
  • Airflow
    • Airflow-Ninja
      • Introduction and Goal
      • Tutorial: Settings
      • Tutorial: Module Import, Alert
  • Docker
    • Production with Docker
      • Customizing root directory
  • Network
    • Network-Handbook
      • Introduction and Goal
      • OSI7Layer
      • DNS
      • SSL/TLS
  • Comupter Architecture
    • Basic
      • Introduction and Goal
      • Chapter 1. The Internal Language of Computers
      • Chapter 2. Combinatorial Logic
      • Chapter 3. The Essentials of Memory and Disk Sequential Logic
    • Hands-on
      • Introduction and Goal
      • theory
        • Chapter 1. Logic Gates
        • Chapter 2. ALU
      • project
        • Project 1. Elementary logic gates implement
        • Project 2. Boolean Arithmetic
  • Java
    • Readable Code
      • 학습 목적
      • 추상화
      • 논리적 사고 흐름
      • 객체지향 이론
      • 객체지향 코드 적용하기
      • 코드 다듬기
      • 읽기 좋은 코드를 도와줄 조언들
  • Spring Boot
    • Practical Testing
      • 테스트 사전 지식
      • 스프링 레이어드 아키텍처 테스트하기
        • Persistence Layer
        • Business Layer
    • 스프링 핵심 원리 - 기본편
      • 객체 지향 설계와 스프링
      • 스프링 핵심 원리 이해
        • 예제 만들기
        • 객체 지향 원리 적용
        • 스프링 컨테이너와 스프링 빈
  • Python
    • Effective Python
      • Introduction and Goal
      • Closure: Lazy Evaluation And Eager Evaluation
      • Python public attributes are better getter-setter
      • No refactoring attribute, we can use property decorator
      • You can do it, but it means you don't have to
  • Playgrounds
    • Java Playground
      • 학습 목적
      • 숫자 야구 게임
        • 학습 테스트
        • 문자열 계산기
        • 숫자 야구 게임 구현
        • 숫자 야구 게임 다시 구현하기
      • 자동차 경주
        • 문자열 덧셈 계산기
        • 자동차 경주 미션 구현
      • 좌표 계산기
        • 연료 주입
        • 좌표 계산기 미션 구현
    • Infra Playground
      • VPC: 망분리 그리고 테스트
      • 컨테이너 사전 지식
      • 화면 성능 개선 전 학습 테스트
      • SSM: Session Manager
      • SQL, 이 정도는 알아야지 😎
      • Subway-Map
        • 망 구성하기
        • 서버 구성하기
        • 화면 성능 개선하기
      • Conference Platform
        • 망 구성하기
        • 서버 구성하기
        • 화면 성능 개선하기
  • Tools
    • SOPS
    • Bruno
    • 🖥️FCK-NAT
    • 🧊Pulumi
Powered by GitBook
On this page
  1. Playgrounds
  2. Java Playground
  3. 좌표 계산기

연료 주입

요구사항

우리 회사는 렌터카를 운영하고 있다. 현재 보유하고 있는 차량은 Sonata 2대, Avante 1대, K5 2대로 총 5대의 차량을 보유하고 있다. 우리 회사는 고객이 인터넷으로부터 예약할 때 여행할 목적지의 대략적인 이동거리를 입력 받는다. 이 이동거리를 활용해 차량 별로 필요한 연료를 주입한다.

차량 별로 주입해야 할 연료량을 확인할 수 있는 보고서를 생성해야 한다.

차종 별 연비
* Sonata : 10km/리터
* Avante : 15km/리터
* K5 : 13km/리터

상속을 이용한 문제 풀이


package abstract_rentcar;

public abstract  class AbstractRentCar {
    private final int distance;

    public AbstractRentCar(int distance) {
        this.distance = distance;
    }

    public abstract int getFuelEfficiency();
    public abstract String getCarName();

    public String getRentCarInfo() {
        return getCarName() + " : " + getRequiredRemainingFuel() + "리터";
    }

    public int getRequiredRemainingFuel() {
        return distance / getFuelEfficiency();

    }
}
package abstract_rentcar;

public class K5 extends AbstractRentCar {

    private final int fuelEfficiency = 13;
    private final String carName = "K5";

    public K5(int distance) {
        super(distance);
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }
}
package abstract_rentcar;

public class Sonata extends AbstractRentCar {

    private final int fuelEfficiency = 10;
    private final String carName = "Sonata";

    public Sonata(int distance) {
        super(distance);
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }
}
package abstract_rentcar;

public class Avante extends AbstractRentCar {

    private final int fuelEfficiency = 15;
    private final String carName = "Avante";

    public Avante(int distance) {
        super(distance);
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }
}

인터페이스를 이용한 문제 풀이


package implement_rentcar;

public interface ImplementRentCar {

    int getFuelEfficiency();

    String getCarName();

    String getRentCarInfo();

    int getRequiredRemainingFuel();

}
package implement_rentcar;

public class K5 implements ImplementRentCar {

    private final int fuelEfficiency = 13;
    private final String carName = "K5";
    private final int distance;

    public K5(int distance) {
        this.distance = distance;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public String getRentCarInfo() {
        return getCarName() + " : " + getRequiredRemainingFuel() + "리터";
    }

    @Override
    public int getRequiredRemainingFuel() {
        return distance / getFuelEfficiency();
    }


}
package implement_rentcar;

public class Sonata implements ImplementRentCar {

    private final int fuelEfficiency = 10;
    private final String carName = "Sonata";
    private final int distance;

    public Sonata(int distance) {
        this.distance = distance;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public String getRentCarInfo() {
        return getCarName() + " : " + getRequiredRemainingFuel() + "리터";
    }

    @Override
    public int getRequiredRemainingFuel() {
        return distance / getFuelEfficiency();
    }
}
package implement_rentcar;

public class Avante implements ImplementRentCar {

    private final int fuelEfficiency = 15;
    private final String carName = "Avante";
    private final int distance;

    public Avante(int distance) {
        this.distance = distance;
    }

    @Override
    public int getFuelEfficiency() {
        return fuelEfficiency;
    }

    @Override
    public String getCarName() {
        return carName;
    }

    @Override
    public String getRentCarInfo() {
        return getCarName() + " : " + getRequiredRemainingFuel() + "리터";
    }

    @Override
    public int getRequiredRemainingFuel() {
        return distance / getFuelEfficiency();
    }
}

위 두 가지 문제 접근법을 살펴보자면, 상속 과 인터페이스 이다.

상속을 이용한 코드는 비교적 부모의 메서드를 사용하는 자식의 입장에서 별도로 구현 할 필요가 없기 때문에 코드 작성 양이 굉장히 줄어들었다.

반면, 인터페이스를 활용한 코드는 자식이 모든 것을 구현해야 하기 때문에 코드의 양이 상대적으로 많아진 모습이다.

이 둘의 차이는 "메서드 구현 담당을 어디서 하느냐?" 의 관점에서 바라볼 수 있는데 애석하게도 단순한 코드가 올바른 접근 방법은 아니라는 것이다.

상속이 갖고 있는 단점은 부모가 모든 것을 구현했기 때문에 자식과 강결한 결합 관계를 나타낸다.

  • 강결합인 경우 유연하지 못하기 때문에 사소한 요구사항에 의해 변경사항을 반영하기 굉장히 까다롭다는 점이다.

그럼, 이런 단점이 두각된 설계 방식을 왜 사용할까?

  • 프레임워크 수준에서 정의된 부모 - 자식 관계의 코드 재사용이 훨씬 용이한 경우, 부모가 갖고 있는 메서드의 변경이 없을 경우

인터페이스는 상속과 반대로 코드를 재사용할 수 없어 중복 코드가 많이 발생하는 단점이 나타난다.

  • 하나의 공통 인터페이스는 여러 곳에서 구현하기 때문에 확장에 용이함이 있다.

이번 진행한 미션은 상속과 인터페이스에 대해 다루었고 두 설계 방식을 코드로 구현 하면서 어떤 관점에서 편리한지, 불편한지 등 몸소 경험할 수 있는 미션이었다.

또한 해당 미션은 학습 테스트라는 방식으로 제공 되었는데, 학습 하는 대상이 훨씬 더 접근하기 쉽도록 스켈레톤 코드가 일부 제공 되고 그 코드를 퍼즐 맞추듯 작성한 뒤 모든 테스트를 통과 시키면 된다.

이 방법은 코드 작성자가 직접 테스트를 할 필요 없이 작성된 테스트가 통과 할 수 있는 선에서 많은 리팩터링을 할 수 있도록 만들어내어 편리했다.

Previous좌표 계산기Next좌표 계산기 미션 구현

Last updated 2 months ago