본문 바로가기

Program/Spring

객체 지향 설계 원칙(SOLID 원칙) ,OCP, MVC

22.10.26 - 객체 지향 설계 원칙(SOLID 원칙) ,OCP, MVC

1강-스프링 핵심원리.pdf

이론


객체 지향 설계 원칙(SOLID 원칙)

  • SRP(단일 책임 원칙)
    • 한 개에 여러개의 작업을 시키면 안됨
  • OCP(개방-패쇄 원칙)
    • 상위 객체는 하위 객체에 일을 시킬떄 특정해서 일을 시키면 안되며 알 필요도 없다.
    • 직접 Human employee = new Kim(); 이라고 하면 유지 보수에 안좋으므로 아래의 예시코드처럼 사용한다.
  • LSP(리스코프 치환 원칙)
    • 인터페이스를 벗어나지 않고 동작
  • ISP(인터페이스 분리 원칙)
    • 운전 면허를 따는데 운전 + 정비를 해야하는 것이 인터페이스를 하나로 통합한 것
  • DIP(의존관계 역전 원칙)
    • 구현 클래스에 의존하지 말고 역할에 의존

스프링컨테이너 : 의존 객체 생애주기 관리

코드


의존 관계의 이해

Interface

  • Human

      package com.spring.basic;
    
      public interface Human {
    
          void breath();
          void walk();
      }
    

class

  • Kim

      package com.spring.basic;
    
      public class Kim implements Human{
          @Override
          public void breath() {
    
          }
    
          @Override
          public void walk() {
    
          }
      }
  • Park

      package com.spring.basic;
    
      public class Park implements Human{
          @Override
          public void breath() {
    
          }
    
          @Override
          public void walk() {
    
          }
      }
  • Company

      package com.spring.basic;
    
      //회사는 반드시 직원(사람)이 필요하다
      //회사는 사람에게 의존한다.
      //회사는 사람을 컴포지션(속성) 해야한다.
    
      //객체는 구현체(구체적인 사람)에 의존하면 안되고 역할에 의존
      public class Company {
    
      //    private Kim employee = new Kim() =>
          private Human employee = new Park();//=>다형성 :
      }

OCP

Interface

  • Human

      package com.spring.basic;
    
      public interface Human {
    
          void breath();
          void walk();
      }

Java

  • Company

      package com.spring.basic;
    
      //회사는 반드시 직원(사람)이 필요하다
      //회사는 사람에게 의존한다.
      //회사는 사람을 컴포지션(속성) 해야한다.
    
      //객체는 구현체(구체적인 사람)에 의존하면 안되고 역할에 의존
      public class Company {
    
          private Human employee;
    
      //    의존성 주입(외부에서 의존을 받겠다.)
          public Company(Human employee) {
              this.employee = employee;
          }
    
          public void work(){
              System.out.println("회사에서 숨쉬기");
              employee.breath();
          }
      }
  • House

      package com.spring.basic;
    
      public class House {
    
          private Human father;
    
          public House(Human father) {
              this.father = father;
          }
    
          public void sleep(){
              System.out.println("집에서 낮잠");
              father.breath();
          }
      }
  • School

      package com.spring.basic;
    
      public class School{
    
          private Human student;
    
          public School(Human student) {
              this.student = student;
          }
    
          public void study() {
              System.out.println("학교에서 숨쉬기중~~");
              student.breath();
          }
      }

  • Kim

      package com.spring.basic;
    
      public class Kim implements Human{
          @Override
          public void breath() {
              System.out.println("kim");
          }
    
          @Override
          public void walk() {
    
          }
      }
  • Park

      package com.spring.basic;
    
      public class Park implements Human{
          @Override
          public void breath() {
              System.out.println("Park");
          }
    
          @Override
          public void walk() {
    
          }
      }

  • Office

      package com.spring.basic;
    
      public class Office {
    
          // 객체를 생성해서 주입한다.
          public Human human() {
              return new Park();
          }
          public School school() {
              return new School(human());
          }
          public House house() {
              return new House(human());
          }
          public Company company() {
              return new Company(human());
          }
      }

Test실행(Ctrl+shift+t)

package com.spring.basic;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class OfficeTest {

    @Test
    void test(){
        Office office = new Office();
        Company company = office.company();
        School school = office.school();
        House house = office.house();

        company.work();
        school.study();
        house.sleep();

    }

}

OCP코드를 Spring으로

Java

  • Company

      package com.spring.basic;
    
      import org.springframework.stereotype.Component;
    
      //객체는 구현체(구체적인 사람)에 의존하면 안되고 역할에 의존
      @Component
      public class Company {
    
          private Human employee;
    
      //    의존성 주입(외부에서 의존을 받겠다.)
              @Autowired
          public Company(@Qualifier("kim") Human employee) {
              this.employee = employee;
          }
    
          public void work(){
              System.out.println("회사에서 숨쉬기");
              employee.breath();
          }
      }
  • House

      package com.spring.basic;
      @Componet
      public class House {
    
          private Human father;
    
        @Autowired
          public House(@Qualifier("kim")Human father) {
              this.father = father;
          }
    
          public void sleep(){
              System.out.println("집에서 낮잠");
              father.breath();
          }
      }
  • School

      package com.spring.basic;
      import org.springframework.stereotype.Component;
    
      @Component
      public class School{
    
          private Human student;
    
              @Autowired
          public School(@Qualifier("kim") Human student) {
              this.student = student;
          }
    
          public void study() {
              System.out.println("학교에서 숨쉬기중~~");
              student.breath();
          }
      }

  • Kim

      package com.spring.basic;
      import org.springframework.stereotype.Component;
    
      @Component("kim")
      public class Kim implements Human{
          @Override
          public void breath() {
              System.out.println("kim");
          }
    
          @Override
          public void walk() {
    
          }
      }
  • Park

      package com.spring.basic;
      import org.springframework.stereotype.Component;
    
      @Component("park")
      public class Park implements Human{
          @Override
          public void breath() {
              System.out.println("Park");
          }
    
          @Override
          public void walk() {
    
          }
      }

  • Office

      package com.spring.basic;
    
      public class Office {
    
          // 객체를 생성해서 주입한다.
          public Human human() {
              return new Park();
          }
          public School school() {
              return new School(human());
          }
          public House house() {
              return new House(human());
          }
          public Company company() {
              return new Company(human());
          }
      }

Test실행(Ctrl+shift+t)

package com.spring.basic;

import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static org.junit.jupiter.api.Assertions.*;

class AppConfigTest {

    @Test
    void springTest() {

        //설정파일 읽어들이기
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext(AppConfig.class);

        Company company = context.getBean(Company.class);
        School school = context.getBean(School.class);
        House house = context.getBean(House.class);

        company.work();
        school.study();
        house.sleep();
    }

}

MVC


DB연결 ⇒ git에 올릴때 DB정보가 담긴 내용을 업로드를 막음

  • webmvc/src/main/java/com/spring/webmvc/config/DataBaseConfig.java

      package com.spring.webmvc.config;
    
      import com.zaxxer.hikari.HikariConfig;
      import com.zaxxer.hikari.HikariDataSource;
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.context.annotation.PropertySource;
    
      import javax.sql.DataSource;
    
      //DB 접속 관련 설정(접속, 커넥션풀)
      @Configuration
      @PropertySource("classpath:db_info.properties")
      public class DataBaseConfig {
    
          @Value("${local.db.username}")
          private String username;
    
          @Value("${local.db.password}")
          private String password;
          @Value("${local.db.url}")
          private String url;
    
      //  Bean -> java  public (class) (id)(){}
          @Bean
          public DataSource dataSource(){
              HikariConfig config = new HikariConfig();
              config.setUsername(username);
              config.setPassword(password);
              config.setJdbcUrl(url);
              config.setDriverClassName("org.mariadb.jdbc.Driver");
    
              return new HikariDataSource(config);
    
          }
      }
  • webmvc/src/main/resources/application.properties

      #내부 tomcat 포트 설정
      server.port=8181
  • webmvc/src/main/resources/db_info.properties

      local.db.username=root
      local.db.password=mariadb
      local.db.url=jdbc:mariadb://localhost:3306/spring10
  • git 업로드 막는 방법

    프로젝트 파일 중 .gitignore에 파일 경로를 입력

    Untitled

ViewResolver

  • webmvc/src/main/java/com/spring/webmvc/HomeController.java

      @GetMapping("/hello")
          public String hello(){
              return "hello";
          }
      }
  • webmvc/src/main/java/com/spring/webmvc/config/ViewConfig.java ⇒ java로 만들기

      package com.spring.webmvc.config;
    
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.view.InternalResourceViewResolver;
    
      @Configuration
      public class ViewConfig {
          ViewResolver 만드는 코드
          @Bean
          public InternalResourceViewResolver resolver(){
              InternalResourceViewResolver resolver = new InternalResourceViewResolver();
              resolver.setPrefix("/WEB-INF/views/");
              resolver.setSuffix(".jsp");
    
              return resolver;
          }
      }
  • webmvc/src/main/resources/application.properties ⇒ properties로 만들기

      #view resolver
      spring.mvc.view.prefix=/WEB-INF/views/
      spring.mvc.view.suffix=.jsp

-