1. 비지니스 요구사항과 설계

회원

  • 회원을 가입하고 조회할 수 있다.
  • 회원은 일반과 VIP 두 가지 등급이 있다.
  • 회원 데이터는 자체 DB를 구축할 수 있고, 외부 시스템과 연동할 수 있다. (미확정)

주문과 할인 정책

  • 회원은 상품을 주문할 수 있다.
  • 회원 등급에 따라 할인 정책을 적용할 수 있다.
  • 할인 정책은 모든 VIP는 1000원을 할인해주는 고정 금액 할인을 적용해달라. (나중에 변경 될 수 있다.)
  • 할인 정책은 변경 가능성이 높다. 회사의 기본 할인 정책을 아직 정하지 못했고, 오픈 직전까지 고민을 미루고 싶다. 최악의 경우 할인을 적용하지 않을 수도 있다. (미확정)

 


 

2. 개발 

  • 순수하게 자바 코드만 사용해서 개발
  • 역할(인터페이스)과 구현(구현체)을 분리해서 자유롭게 구현 객체를 조립할 수 있게 설계했다. 덕분에 회원 저장소는 물론이고, 할인 정책도 유연하게 변경할 수 있다.

 

새로운 할인 정책 개발

  • 유연한 설계가 가능하도록 객체지향 설계 원칙을 준수하며 개발했다.
  • 기존의 할인 정책인 FixDiscountPolicy 대신 새로운 할인 정책 RateDiscountPolicy로 변경하면 된다.
public class OrderServiceImpl implements OrderService {
	// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
	private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}

 

 

문제점 발견

  • 우리는 역할과 구현을 충실하게 분리했다. -> OK
  • 다형성도 활용하고, 인터페이스와 구현 객체를 분리했다. -> OK
  • OCP, DIP 같은 객체지향 설계 원칙을 충실히 준수했다 ->  NO
    • DIP 위반: 추상(인터페이스) 뿐만 아니라 구체(구현) 클래스에도 의존하고 있다.
    • OCP 위반: 지금 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 준다!

 

의존관계

기대했던 의존관계
실제 의존관계

클라이언트인 OrderServiceImpl 이 DiscountPolicy 인터페이스 뿐만 아니라 FixDiscountPolicy 인 구체 클래스도 함께 의존하고 있다. 실제 코드를 보면 의존하고 있다! DIP 위반

 

정책 변경

FixDiscountPolicy 를 RateDiscountPolicy 로 변경하는 순간 OrderServiceImpl 의 소스 코드도 함께 변경해야 한다! OCP 위반

 

문제 해결

DIP를 위반하지 않도록 인터페이스에만 의존하도록 의존관계를 변경하면 된다.

public class OrderServiceImpl implements OrderService {
	//private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
 	private DiscountPolicy discountPolicy;
}

인터페이스에만 의존하도록 설계와 코드를 변경했다.

❌ 또 다른 문제 발생! -> 구현체가 없어서 실행을 해보면 NPE(null pointer exception)가 발생한다.

 

해결방안

이 문제를 해결하려면 누군가가 구현 객체를 대신 생성하고 주입해주어야 한다.

그 누군가는 바로 스프링!!

 

 

 

다음 글 보러가기😋

2022.09.13 - [Spring] - 스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리2

 

스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리2

1. 관심사의 분리 AppConfig 등장 애플리케이션의 전체 동작 방식을 구성(config)하기 위해, 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스 AppConfig를 만든다. AppConfig는 애플리케

yiseul-coding.tistory.com

 

1. 스프링이란?

스프링이라는 단어는 문맥에 따라 다르게 사용된다.

  1. 스프링 DI 컨테이너 기술
  2. 스프링 프레임워크
  3. 스프링 부트 등을 모두 포함한 스프링 생태계

 

스프링 프레임워크

  • 스프링의 핵심 기술: 스프링 DI 컨테이너, AOP, 이벤트, 기타
  • 웹 기술: 스프링 MVC, 스프링 WebFlux
  • 데이터 접근 기술: 트랜잭션, JDBV, ORM지원, XML 지원

 

스프링 부트

  • 스프링을 편리하게 사용할 수 있도록 지원
  • 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성 - Tomcat 같은 웹 서버를 내장
  • 손쉬운 빌드 구성을 위한 starter 종속성 제공
  • 스프링과 3rd parth(외부) 라이브러리 자동 구성

 


 

2. 스프링의 핵심

  • 스프링은 객체 지향 언어가 가진 강력한 특징을 살려내는 프레임워크
  • 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크

 


 

3. 좋은 객체 지향 프로그래밍

객체 지향 프로그래밍

  • 객체들의 모임으로 파악
  • 각각의 객체는 메시지를 주고 받고, 데이터를 처리 (협력)
  • 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게
  • 객체 지향 특징 중 다형성을 활용

 

다형성 - 역할과 구현을 분리

  • 역할 = 인터페이스
  • 구현 = 인터페이스를 구현한 클래스, 즉 구현 객체
  • 역할과 구현으로 구분하면 단순해지고, 유연해지며 변경도 편리
  • 확장 가능한 설계
  • 장점
    • 클라이언트는 대상의 역할(인터페이스)만 알면 된다.
    • 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
    • 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
    • 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.

 

다형성의 본질

  • 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다.
  • 다형성의 본질을 이해하려면 협력이라는 객체사이의 관계에서 시작해야한다.
  • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.

 

💡인터페이스를 안정적으로 잘 설계하는 것이 중요!!

 

좋은 객체 지향 설계의 5가지 원칙(SOLID)

  • SRP: 단일 책임 원칙(Single Responsibility Principle)
  • OCP: 개방-폐쇄 원칙 (Open/Closed Principle)
    • 소프트웨어 요소는 확장에는 열려 있으니 변경에는 닫혀 있어야 한다.
  • LSP: 리스코프 치환 원칙 (Liskov Substitution Principle)
  • ISP: 인터페이스 분리 원칙 (Interface Segregation Principle)
  • DIP: 의존관계 역전 원칙 (Dependency Inversion Principle)
    • 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”
    • 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻

 

정리

  • 다형성 만으로는 쉽게 부품을 갈아 끼우듯이 개발할 수 없다.
  • 다형성 만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다.
  • 다형성 만으로는 OCP, DIP를 지킬 수 없다.

 

스프링 이야기에 왜 객체 지향 이야기가 나오는가?

  • 스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원
    • DI(Dependency Injection): 의존관계, 의존성 주입
    • DI 컨테이너 제공
  • 클라이언트 코드의 변경 없이 기능 확장
  • 쉽게 부품을 교체하듯이 개발

 

 

 

다음 글 보러가기😋

2022.09.13 - [Spring] - 스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리1

 

스프링 핵심 원리 - 기본편 | 스프링 핵심 원리 이해 정리1

1. 비지니스 요구사항과 설계 회원 회원을 가입하고 조회할 수 있다. 회원은 일반과 VIP 두 가지 등급이 있다. 회원 데이터는 자체 DB를 구축할 수 있고, 외부 시스템과 연동할 수 있다. (미확정) 주

yiseul-coding.tistory.com

 

스프링MVC로 프로젝트 진행 중에 404 에러가 떴습니다.

WARN : org.springframework.web.servlet.PageNotFound - No mapping for GET

이 에러가 뜬다면 먼저 체크해봐야할 것이 4가지 있습니다.

1. web.xml에 DispatcherServlet 선언이 잘 되어있는지 확인

2. servlet-context.xml 확인

<context:component-scan base-package="패키지명"/>
<mvc:annotation-driven/>


3. 컨트롤러 클래스에 @Controller와 url 매핑이 잘 되어 있는지 확인

보통은 위에 3가지를 체크하면 해결이 되지만!
위에 3가지를 모두 체크해도 계속해서 404 오류가 난다면, 프로젝트 이름으로 된 {project_name}.iml 파일을 확인해보세요!! (ex. 프로젝트 이름이 boardWeb이라면 boardWeb.iml 파일)

파일에서 해당 부분을 삭제하면 정상 실행됩니다 :)

저거 지우고 3일간의 오류 찾기는 겨우 끝이 났어요,,,,,,,,,, 모두들 오류 잘 해결하세요.

Spring MVC와 JPA로 개발하던 중 DB에 한글이 깨져서 들어간 것을 확인했다ㅠㅠ

그래서 구글링을 통해서 찾아봤는데
대부분 dataSource url에 "useUnicode=true&characterEncoding=utf8" 을 추가하라고 나온다.

jdbc:mysql://localhost:3306/DB이름?useUnicode=true&characterEncoding=utf8

하지만 내 경우에는 이 방식으로는 해결을 못했다..

데이터가 DB에 들어가기 전에 콘솔창에 출력을 해서 확인해보니 이미 한글이 깨져있었다. DB 들어갈 때 깨지는 건 아니라는 소리
그렇다면 필터 문제인가 싶어서 보니 필터 url이 문제였다..

web.xml을 밑에와 같이 수정하니 한글 깨짐 현상이 사라졌다!!

    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


git push origin master 명령어를 사용했더니

remote: Support for password authentication was removed on August 13, 2021. Please use a
personal access token instead.

이런 오류가 떴다.

에러원인은
더 이상 패스워드 기반 인증을 지원하지 않아서 생긴 것

Creating a personal access token - GitHub Docs

Creating a personal access token - GitHub Docs

Note: If you use GitHub CLI to authenticate to GitHub on the command line, you can skip generating a personal access token and authenticate via the web browser instead. For more information about authenticating with GitHub CLI, see gh auth login. Personal

docs.github.com

이걸 보고 그대로 따라해서 토큰을 발행한다.
그 후 패스워드 자리에 토큰 복사해서 붙여넣으면

성공!!

'Git' 카테고리의 다른 글

[GitHub] 깃허브 사용법  (0) 2022.01.29

스프링하다가 콘솔 창에 한글이 깨질 때

밑의 사진처럼 VM options에

-Dfile.encoding=UTF-8

을 입력하고 Apply 후 Ok 누르면 끝~

스프링프레임워크를 공부하다가 

<context:annotation-config/>

 

DI를 공부하면서 xml 파일에 위와 같은 코드를 적었는데 빨간 줄이 뜨면서 오류가 났다.

구글링을 통해 찾아보니

 

이 코드를 (수정 전)

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="http://www.springframework.org/schema/tool
	http://www.springframework.org/schema/tool/spring-tool.xsd"

 

밑에처럼 바꿔주면 해결된다!

(수정 후)

xmlns:context="http://www.springframework.org/schema/context"

// xsi:schemaLocation에 밑의 주소 추가
xsi:schemaLocation="http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd"

node.js에서 MySQL을 연동할 때, 이런 오류가 났습니다.

Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client at Handshake.Sequence._packetToError

 

구글링으로 해결책을 찾아보니

 

ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘사용할패스워드’

 

MySQL에서 위의 명령어를 입력하면 된다고 합니다.

 

위의 명령어를 실행시켜줬더니 오류 해결~!

 

 

 

참고

https://stackoverflow.com/questions/50093144/mysql-8-0-client-does-not-support-authentication-protocol-requested-by-server

https://www.acmicpc.net/problem/19623

 

19623번: 회의실 배정 4

서준이는 아빠로부터 N개의 회의와 하나의 회의실을 선물로 받았다. 각 회의는 시작 시간, 끝나는 시간, 회의 인원이 주어지고 한 회의실에서 동시에 두 개 이상의 회의가 진행될 수 없다. 단,

www.acmicpc.net

 

내 풀이😊

import heapq
import sys
input = sys.stdin.readline

n = int(input())

# 회의 정보를 담을 리스트
array = []
for _ in range(n):
  # 시작 시간, 끝나는 시간, 회의 인원 입력
  array.append(list(map(int, input().split())))

# 끝나는 시간을 기준으로 오름차순 정렬
array.sort(key=lambda x:x[1])

for _ in range(n):

 

 

 

백준 문제 풀이 깃허브 주소입니다 :)

https://github.com/Yiseull/baekjoon

 

 

GitHub - Yiseull/baekjoon

Contribute to Yiseull/baekjoon development by creating an account on GitHub.

github.com

 

https://www.acmicpc.net/problem/19622

 

19622번: 회의실 배정 3

서준이는 아빠로부터 N개의 회의와 하나의 회의실을 선물로 받았다. 각 회의는 시작 시간, 끝나는 시간, 회의 인원이 주어지고 한 회의실에서 동시에 두 개 이상의 회의가 진행될 수 없다. 단,

www.acmicpc.net

 

내 풀이😊

import sys
input = sys.stdin.readline

n = int(input())

# 회의 정보를 담을 리스트
array = []
for _ in range(n):
  # 시작 시간, 끝나는 시간, 회의 인원 입력
  array.append(list(map(int, input().split())))

# 시작 시간 기준 오름차순 정렬
array.sort()

dp = [0] * n
dp[0] = array[0][2]
for i in range(1, n):
  dp[i] = max(dp[i - 1], dp[i - 2] + array[i][2])

print(dp[n - 1])

시간복잡도는 O(NlogN)입니다.

 


import sys
input = sys.stdin.readline

이 코드가 없어도 결과는 맞았습니다!! 가 나옵니다. 

 

밑에는 위의 코드를 넣었을 때고, 위에는 넣지 않았을 때입니다.

위의 코드의 유무에 따라 시간 차이가 꽤 나서 시간초과 판정을 받을 때, 위의 코드를 삽입해주는 게 좋습니다!

 

 

 

백준 문제 풀이 깃허브 주소입니다 :)

https://github.com/Yiseull/baekjoon

 

GitHub - Yiseull/baekjoon

Contribute to Yiseull/baekjoon development by creating an account on GitHub.

github.com

+ Recent posts