스프링 프레임워크(Spring Framework)는 자바 언어를 위한 오픈소스 경량급 애플리케이션 프레임워크
객체 지향 프로그래밍에서 유지보수와 확장성을 높이기 위한 다섯 가지 설계 원칙
// SRP X - 한 클래스에 여러가지 기능이 있다.
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public boolean isValid() {
// 유효성 검사
return true;
}
public void save() {
// 데이터 저장
}
}
// SRP O - 클래스마다 기능을 쪼갰다.
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
public class UserValidator {
public boolean isValid(User user) {
// 유효성 검사
return true;
}
}
public class UserDAO {
public void save(User user) {
// 데이터 저장
}
}
public interface Area {
double calculateArea();
}
public interface Volume {
double calculateVolume();
}
public class Rectangle implements Area {
private double width;
private double height;
public double calculateArea() {
return width * height;
}
}
public class Cube implements Area, Volume {
private double width;
private double height;
private double depth;
public double calculateArea() {
return 2 * (width * height + width * depth + height * depth);
}
public double calculateVolume() {
return width * height * depth;
}
}
public class RedLight {
public void turnOn() {
System.out.println("Red Light turned on");
}
}
public class Switch {
private RedLight light;
public Switch() {
this.light = new RedLight();
}
public void flip() {
if (light != null) {
light.turnOn();
}
}
}
public interface Light {
void turnOn();
}
public class RedLight implements Light {
@Override
public void turnOn() {
System.out.println("Red Light turned on");
}
}
public class Switch {
private Light light;
public Switch(Light light) {
this.light= light;
}
public void flip() {
if (light!= null) {
light.turnOn();
}
}
}
package com.study.springstudy.chap01;
/*
* @problem - 호텔 클래스에서 직접 객체를 생성하면
* 나중에 의존객체를 변경해야 될 때
* 직접 호텔 클래스를 수정해야 되므로
* OCP를 위반하게 됨.
* 그리고 headChef가 변경되면 레스토랑 안에
* 쉐프도 같이 바뀌어야 할 때 2군데를 수정해야 함.
*/
public class Hotel {
// 레스토랑
private AsianRestaurant restaurant = new AsianRestaurant();
// 헤드쉐프
private KimuraChef headChef = new KimuraChef();
// 호텔을 소개하는 기능
public void inform() {
System.out.printf("우리 호텔의 레스토랑은 %s입니다. " +
"그리고 헤드쉐프는 %s입니다.\n"
, restaurant.getClass().getSimpleName()
, headChef.getClass().getSimpleName());
restaurant.orderMenu();
}
}
package com.study.springstudy.chap02;
/*
* @Solution
* - 먼저 DIP를 해결하기 위해 구체적인 객체 대신
* 추상적인 역할에 의존하게 코드를 개선
*
* @problem - 추상화를 했지만 여전히 의존객체를 바꾸려면
* 코드를 직접 변경해야 한다.
*/
public class Hotel {
// 레스토랑
private Restaurant restaurant = new WesternRestaurant();
// 헤드쉐프
private Chef headChef = new KimuraChef();
// 호텔을 소개하는 기능
public void inform() {
System.out.printf("우리 호텔의 레스토랑은 %s입니다. " +
"그리고 헤드쉐프는 %s입니다.\n"
, restaurant.getClass().getSimpleName()
, headChef.getClass().getSimpleName());
restaurant.order();
}
}
package com.study.springstudy.chap03;
/*
* @Solution
* - 객체 생성의 제어권을 이 클래스에서
* 다른 클래스로 이전한다.
* ex) new 생성자(); - 이 문법을 담당클래스를 정해서 몰아서 수행시킴
* - 호텔 객체 생성시 반드시 객체를 전달하도록 강요 (생성자를 통해서)
*
* // 제어의 역전(IoC) : 객체 생성의 제어권을 외부로 넘긴다.
// 의존성 주입(DI) : 외부에서 생성된 객체를 주입받는 개념
*/
public class Hotel {
// 레스토랑
private Restaurant restaurant;
// 헤드쉐프
private Chef headChef;
// restaurant, headChef 있어야 Hotel 지을 수 있어~
public Hotel(Restaurant restaurant, Chef headChef) {
this.restaurant = restaurant;
this.headChef = headChef;
}
// 호텔을 소개하는 기능
public void inform() {
System.out.printf("우리 호텔의 레스토랑은 %s입니다. " +
"그리고 헤드쉐프는 %s입니다.\n"
, restaurant.getClass().getSimpleName()
, headChef.getClass().getSimpleName());
restaurant.order();
}
}
package com.study.springstudy.chap03.config;
import com.study.springstudy.chap03.*;
// 객체 생성의 제어권을 모두 가지고 온 객체
public class HotelManager {
// 쉐프 객체 생성
public Chef chef1() {
return new JannChef();
}
public Chef chef2() {
return new KimuraChef();
}
// 요리 코스객체 생성
public Course course1() {
return new FrenchCourse();
}
public Course course2() {
return new SushiCourse();
}
// 레스토랑 객체 생성
public Restaurant restaurant1() {
return new WesternRestaurant(chef1(), course1());
}
public Restaurant restaurant2() {
return new AsianRestaurant(chef2(), course2());
}
// 호텔 객체 생성
public Hotel hotel() {
return new Hotel(restaurant2(), chef2());
}
}