Goal
디자인 패턴의 개념을 이해한다.
디자인 패턴의 구조를 이해한다.
디자인 패턴의 분류를 이해한다.
디자인 패턴의 종류를 이해한다.
디자인 패턴이란
소프트웨어를 설계할 때 특정 맥락에서 자주 발생하는 고질적인 문제들이 또 발생했을 때 재사용할 할 수있는 훌륭한 해결책
“바퀴를 다시 발명하지 마라(Don’t reinvent the wheel)”
이미 만들어져서 잘 되는 것을 처음부터 다시 만들 필요가 없다는 의미이다.
패턴이란
각기 다른 소프트웨어 모듈이나 기능을 가진 다양한 응용 소프트웨어 시스템들을 개발할 때도 서로 간에 공통되는 설계 문제가 존재하며 이를 처리하는 해결책 사이에도 공통점이 있다. 이러한 유사점을 패턴이라 한다.
패턴은 공통의 언어를 만들어주며 팀원 사이의 의사 소통을 원활하게 해주는 아주 중요한 역할을 한다.
디자인 패턴 구조
콘텍스트(context)
문제가 발생하는 여어 상황을 기술한다. 즉, 패턴이 적용될 수 있는 상황을 나타낸다.
경우에 따라서는 패턴이 유용하지 못한 상황을 나타내기도 한다.
문제(problem)
패턴이 적용되어 해결될 필요가 있는 여러 디자인 이슈들을 기술한다.
이때 여러 제약 사항과 영향력도 문제 해결을 위해 고려해야 한다.
해결(solution)
문제를 해결하도록 설계를 구성하는 요소들과 그 요소들 사이의 관계, 책임, 협력 관계를 기술한다.
해결은 반드시 구체적인 구현 방법이나 언어에 의존적이지 않으며 다양한 상황에 적용할 수 있는 일종의 템플릿이다.
디자인 패턴의 종류
GoF 디자인 패턴
GoF(Gang of Fout)라 불리는 사람들
에리히 감마(Erich Gamma), 리차드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리시디스(John Vissides)
소프트웨어 개발 영역에서 디자인 패턴을 구체화하고 체계화한 사람들
23가지의 디자인 패턴을 정리하고 각각의 디자인 패턴을 생성(Creational), 구조(Structural), 행위(Behavioral) 3가지로 분류했다.
GoF

1.생성(Creational) 패턴
객체 생성에 관련된 패턴
객체의 생성과 조합을 캡슐화해 특정 객체가 생성되거나 변경되어도 프로그램 구조에 영향을 크게 받지 않도록 유연성을  제공한다.
2.구조(Structural) 패턴
클래스나 객체를 조합해 더 큰 구조를 만드는 패턴
예를 들어 서로 다른 인터페이스를 지닌 2개의 객체를 묶어 단일 인터페이스를 제공하거나 객체들을 서로 묶어 새로운 기능을 제공하는 패턴이다.
3.행위(Behavioral)
객체나 클래스 사이의 알고리즘이나 책임 분배에 관련된 패턴
한 객체가 혼자 수행할 수 없는 작업을 여러 개의 객체로 어떻게 분배하는지, 또 그렇게 하면서도 객체 사이의 결합도를 최소화하는 것에 중점을 둔다.

 


    1. GoF 디자인 패턴의 종류
      1.생성(Creational) 패턴
        추상 팩토리(Abstract Factory)
           구제적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패             턴
         팩토리 메서드(Factory Method)
             객체 생성 처리를 서브 클래스로 분리해 처리하도록 캡슐화하는 패턴
         싱글턴(Singleton)
                 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록               하는 패 패턴
      2.구조(Structural) 패턴
         컴퍼지트(Composite)
                여러 개의 객체들로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별 없이 다루게 해주는 패턴
         데커레이터(Decorator)
    2. 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 해주는 패턴
      3.행위(Behavioral) 패턴
         옵서버(Observer)
      한 객체의 상태 변화에 따라 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성하는 패턴
         스테이트(State)
      객체의 상태에 따라 객체의 행위 내용을 변경해주는 패턴
         스트래티지(Strategy)
      행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
         템플릿 메서드(Template Method)
      어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴
         커맨드(Command)
      실행될 기능을 캡슐화함으로써 주어진 여러 기능을 실행할 수 있는 재사용성이 높은 클래스를 설계하는 패턴
      관련된 Post

  • https://gmlwjd9405.github.io/2018/07/06/design-pattern.html 인용

MVC 란 Model-View-Controller 의 약자로 관계를 정리하면 저렇게 할 수 있다고 한다.

게시판 만들기를 하던 중 개념을 알아야 할 필요가 있어서 찾아 보게 되었다

 

💡 MVC 패턴이란?

MVC란 Model-View-Controller의 약자로 애플리케이션을 세 가지 역할로 구분한 개발 방법론입니다. 아래의 그림처럼 사용자가 Controller를 조작하면 Controller는 Model을 통해 데이터를 가져오고 그 데이터를 바탕으로 View를 통해 시각적 표현을 제어하여 사용자에게 전달하게 됩니다.

이러한 패턴을 성공적으로 사용하면, 사용자 인터페이스로부터 비즈니스 로직을 분리하여 애플리케이션의 시작적 요소나 그 이면에서 실행되는 비즈니스 로직을 서로 영향 없이 쉽게 고칠 수 있는 애플리케이션을 만들 수 있게 됩니다.

✔️ 위의 개념을 WEB에 적용 시!

  1. 사용자가 웹사이트에 접속 (Users)
  2. Controller는 사용자가 요청한 웹페이지를 서비스하기 위해서 모델을 호출 (Manipulates)
  3. Model은 데이터베이스나 파일과 같은 데이터 소스를 제어한 후 그 결과를 Return
  4. Controller는 Model이 리턴한 결과를 View에 반영 (Updates)
  5. 데이터가 반영된 View는 사용자에게 보여짐 (Sees)

 

🌈MVC패턴 방식 

MVC 패턴에는 모델 1 방식과 모델 2 방식이 있는데

  • 모델 1 방식: JSP에서 출력과 로직을 전부 처리
  • 모델 2 방식: JSP에서 출력만 처리

로 분류할 수 있습니다.

📌 Model 1

모델 1 방식은 Controller 영역에 View 영역을 같이 구현하는 방식이며, 사용자의 요청을 JSP가 전부 처리합니다. 요청을 받은 JSP는 JavaBean Service Class를 사용하여 웹브라우저 사용자가 요청한 작업을 처리하고 그 결과를 출력합니다.

 

📌 Model 2

모델 2 방식은 웹브라우저 사용자의 요청을 서블릿이 받고 서블릿은 해당 요청으로 View로 보여줄 것인지 Model로 보낼 것인지를 판단하여 전송합니다. 또한 모델 2 방식의 경우 HTML 소스와 JAVA소스를 분리해놓았기 때문에 모델 1 방식에 비해 확장시키기도 쉽고 유지보수 또한 쉽습니다.

📲 모델 (Model)

데이터를 가진 객체를 모델이라고 지칭합니다. 데이터는 내부의 상태에 대한 정보를 가질 수도 있고, 모델을 표현하는 이름 속성으로 가질 수 있습니다. 모델의 상태에 변화가 있을 때 컨트롤러와 뷰에 이를 통보합니다. 이와 같은 통보를 통해 뷰는 최신의 결과를 보여줄 수 있고, 컨트롤러는 모델의 변화에 따른 적용 가능한 명령을 추가, 제거, 수정할 수 있습니다.

모델의 규칙

  • 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야만 함
  • 뷰나 컨트롤러에 대해서 어떠한 정보도 알지 말아야 함
  • 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야 함

 

🖥️ 뷰 (View)

View는 클라이언트 측 기술은 HTML/CSS/Javascript들을 모와둔 컨테이너입니다. 사용자가 볼 결과물을 생성하기 위해 모델로부터 정보를 얻어옵니다.

뷰의 규칙

  • 모델이 가지고 있는 정보를 따로 저장해서는 안됨
  • 모델이나 컨트롤러와 같이 다른 구성 요소를 몰라야 함
  • 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야 함

 

🕹️ 컨트롤러 (Controller)

사용자가 접근한 URL에 따라 사용자의 요청사항을 파악한 후에 그 요청에 맞는 데이터를 Model을 의뢰하고, 데이터를 View에 반영해서 사용자에게 알려줍니다.

모델에 명령을 보냄으로써 뷰의 상태를 변경할 수 있음 => (워드에서 문서 편집)
컨트롤러가 관련된 모델에 명령을 보냄으로써 뷰의 표시 방법을 바꿀 수 있음 => (문서를 스크롤하는 것)

컨트롤러의 규칙

  • 모델이냐 뷰에 대해서 알고 있어야 함
  • 모델이나 뷰의 변경을 모니터링해야 함

 

 

👨🏻‍💻 MVC 패턴을 사용해야 하는 이유

  • 비즈니스 로직과 UI로직을 분리하여 유지보수를 독립적으로 수행가능
  • Model과 View가 다른 컴포넌트들에 종속되지 않아 애플리케이션의 확장성, 유연성에 유리함
  • 중복 코딩의 문제점 제거

 

 

😰 MVC 패턴의 한계

MVC패턴에서 View는 Controller에 연결되어 화면을 구성하는 단위 요소이므로 다수의 View를 가질 수 있습니다. 그리고 Model은 Controller를 통해서 View와 연결되지만, Controller에 의해서 하나의 View에 연결될 수 있는 Model도 여러 개가 될 수 있어 View와 Model이 서로 의존성을 띄게 됩니다. 즉, Controller에 다수의 Model과 View가 복잡하게 연결되어 있는 상황이 발생할 수 도 있습니다.

📗 MVC 패턴 요약

Model - 백그라운드에서 동작하는 비즈니스 로직(데이터) 처리

View - 정보를 화면으로 보여주는 역할.

Controller - 사용자의 입력 처리와 흐름 제어 담당. 화면과 Model과 View를 연결시켜주는 역할

 

 

https://cocoon1787.tistory.com/733 여기 글을 그대로 인용했다

정리를 잘 해놓으셔서 무슨 말 인지 비교가 잘 된다.

 

package com.KoreaIT.java.AM;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

System.out.println("==프로그램 시작==");

Scanner sc = new Scanner(System.in);

int lastArticleId = 0;

while (true) {

System.out.print("명령어 > ");

String command = sc.nextLine();

if (command.length() == 0) {

System.out.println("명령어를 입력해주세요");

continue;

}

if (command.equals("exit")) {

break;

}

if (command.equals("article list")) {

System.out.println("게시글이 없습니다");

} else if (command.equals("article write")) {

int id = lastArticleId + 1;

System.out.print("제목 : ");

String title = sc.nextLine();

System.out.print("내용 : ");

String body = sc.nextLine();

System.out.printf("%d번글이 생성되었습니다\n", id);

lastArticleId++;

} else {

System.out.println("존재하지 않는 명령어입니다");

}

}

System.out.println("==프로그램 끝==");

sc.close();

}

}

 

 

뭔가 늘어났다. 하지만 틀은 비슷하다 여전히 명령어 입력 프로그램을 실행중이고

아까는 명령어에 아무리 무엇을 쳐도 의미가 없었다면 지금은 "article list"와 "article write" 기능을 추가 해놓은 것이다

 

if (command.length() == 0) {

System.out.println("명령어를 입력해주세요");

continue;

명령어를 아무것도 입력하지 않았을 경우 "명령어를 입력해주세요" 를 출력한 뒤

continue로 다시 처음 반복문으로 돌아가는것이다

 

if (command.equals("article list")) {    //만약에 article list라는 명령어를 쳤을경우

System.out.println("게시글이 없습니다");  //일단은 이게 출력되게 해본다. 아직 나의 목적은 무언가가 실행 되기만 하면 된다

} else if (command.equals("article write")) { //그게아닌 article write 명령어를 썼다면

int id = lastArticleId + 1;  //오직 정수만 들어갈 수 있는 변수 id를 lastArticleId에 1을 더하여 해나가겠단 뜻이다

System.out.print("제목 : ");  //print 로 println과 다르게 일렬 출력이 아닌 줄바꿈 출력을 하게 될것이고

String title = sc.nextLine(); //스캐너 타입은 String이라 sc.nextLine();으로 받고있다

System.out.print("내용 : "); //제목과 같다

String body = sc.nextLine(); //제목과 같다

System.out.printf("%d번글이 생성되었습니다\n", id); // printf %d를 하게되면 저장해놓은 변수값이 출력 된다 

lastArticleId++; //그리고 그건 반복문을 실행해 나갈 때 마다 1씩 증가할것이다 ex)1번글이 생성 되었습니다,2번글이...

 

그리고 중요한 점은 반복문 밖에 변수를 선언해야 한다.

int lastArticleId = 0; 를 저장해둬야 반복문을 시행 할 때 마다 초기화 되는 걸 방지 할 수 있다

안그러면 1번째 글만 생성된다는 메세지만 나올것이다

 

 

 

 

package com.KoreaIT.java.AM;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

System.out.println("==프로그램 시작==");

Scanner sc = new Scanner(System.in);

while (true) {

System.out.print("명령어 > ");

String command = sc.nextLine();

if(command.equals("exit")) {

break;

}

}

System.out.println("==프로그램 끝==");

sc.close();

 }

}

명령어 입력을 해보자

while 문으로 무한 루프문을 만들어준다.

프로그램을 시작하면 "==프로그램 시작=="이라는 문구와 함께

명령어 > 

무엇을 입력하든지 명령어만 나오는 프로그램이 작동된다.

여기서 프로그램 종료를 시키기 위한 명령어는

if(command.equals("exit")) {

break;

exit << 를 치면 된다 if문을 중첩시켜서 만약에 커맨드가 exit와 같다면

break를 해 while문을 빠져나와 ==프로그램 끝==  

을 출력 하게 되는 것.

 

자바 백엔드 양성과정에서 오로지 자바로만 게시판 만들기 작업이 시작 되었다.

그 동안의 반복문~객체 지향에 대한 개념까지 반복 숙달할 시간이 충분히 필요하면 좋겠지만

나에게 주어진 시간은 그리 많지 않으니 효율적으로 써야한다.

일단 깃허브에 그날 그날 한 작업물을 올려 일명 잔디 꾸미기를 시작했다.

git bash 프로그램을 깔고 이클립스에서 현재 작업중인 프로젝트에 커서를 올린 뒤 오른쪽 마우스 클릭,Properties에 들어가

Location 주소가 있는 (나같은 경우 C:\Users\PC\eclipse-workspace\2023_03_AM) 곳에 폴더 표시를 클릭하면 내가 하고있는 프로젝트들이 있는 자바 주소가 뜬다.

내가 현재 올리고 싶은 프로젝트 폴더 2023_03_AM에 들어가

이러한 폴더들이 뜬다 자세히는 모르겠다

여기 화면에서 우클릭,git bash 프로그램을 실행 시킨다

먼저, 내 컴퓨터에 있는 git bash와 git hub 계정을 연동 시켜야 한다.

 

git init

git config --global user.name "깃 허브 계정 이름"

git config --global user.email "깃 허브 로그인하는 이메일 계정"

git config --global user.password "깃 허브 로그인하는 이메일 계정의 비밀번호"

 

를 입력하고 

 

git config --list 

로 제대로 입력했는지 확인.

git remote add origin 내가 연동하고픈 깃허브 작업주소

git remote rm origin master(잘못 입력했을 때 삭제!!!! 주의)

 

그런다음 vim .gitignore 를 쳐서 연동에서 제외하고픈 파일을 넣어준다

수업중엔

.settings

.classpath

.project

bin

src

build 정도를 제외했으며 저장하고 나가는건 리눅스와 동일하게esc로 명령어 입력모드 후 wq! 하면 된다

 

 

git add .    ( 리눅스에서도 그렇지만 . 은 현재 폴더를 의미한다)

git commit -m "깃 허브에 저장 될 메시지 입력 한글도 가능"

git push origin master 깃 허브에 푸쉬

 

이런 식으로 연동이 되는 걸 볼 수 있다

 

 

package com.KoreaIT.java.AM;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

System.out.println("==프로그램 시작==");

Scanner sc = new Scanner(System.in);

String command = sc.nextLine();

System.out.printf("입력된 명령어 : %s\n", command);

int command2 = sc.nextInt();

System.out.printf("입력된 명령어 : %d\n", command2);

System.out.println("==프로그램 끝==");

sc.close();

}

}

-명령어 입력 테스트-

명령어 프로그램 확인 차 쓰인 간단한 코드다

import 로 스캐너 기능을 가져와 쓰고있고

간단한 출력을 통해 쓰여있는게 제대로 출력되는지 확인 중이다.

스캐너 기능을 쓴 뒤엔 sc.close();로 닫아준다

+ Recent posts