。゚(*´□`)゚。

코딩의 즐거움과 도전, 그리고 일상의 소소한 순간들이 어우러진 블로그

[네이버클라우드] 클라우드 기반의 개발자 과정 7기/웹프로그래밍

[NC7기-32일차(6월9일)] - 웹프로그래밍 13일차

quarrrter 2023. 6. 9. 17:44

 

1교시 & 2교시&3교시

UML과 패턴의 적용 책 추천

 

클래스 

1. 메서드를 분류

2. 데이터 타입 정의 

 

  메서드 스태틱 변수
(메서드끼리 변수를 공유하고 싶을 때 사용)
클래스
Test Test Test Calculator.class 추가
main() main()
plus()
minus()
multiple()
divide()
main()
plus()
...
------------------------
static int result
plus()
minus()
multiple()
divide()
---------
result
   result = multiple(2,3);
    result = plus(result,7);
    result = minus(result,2);
    result = divide(result,2);
static void init(int a) {
    result = a; }

    init(2);
    multiple(3);
    plus(7);
    minus(2);
    divide(2);
 
패키지+접근제어
(private, (default) <-pakcage privte, protected, public)
getter + private getter + private
Calculator.class
getter + private
Test
bitcamp
-myapp
--test
-util
--Calculator
Calculator
plus()
minus()
----------------
result : int 
  private static int result = 0;해당 클래스를 벗어나면 result 변수를 사용할 수 없음. 결과 값을 왜곡시킬까봐 

public static int getResult() {
    return result;
  }
    Calculator.init(2);
    Calculator.multiple(3);
    Calculator.plus(7);
    Calculator.minus(2);
    Calculator.divide(2);


    System.out.println(Calculator.getResult());
  자바 : int result
UML: result : int 
   

    // 2 * 3 + 7 - 2 / = ?
    // 3 - 1 * 7 + 15 / 3 = ? 
    // static 변수는 계산 결과를 독립적으로 유지할 수 없음. 동시 계산 불가 
    // 인스턴스 변수 : result를 단순 스태틱이면 오직 한개만 쓸수있음. 근데 스태틱 떼어버리구 논스태틱변수로 만들면 여러개 쓸 수 있음 . .. .

class 안에 static int result 는 static field(=class field)라고 부름. 클래스를 로딩할때 메서드에리어에 생김

int result; 는 non static field(instant field) 라고 부름. new 명령을 실행할 때마다 heap에 생성됨 

따라서 개별적으로 여러개 만들어서 관리해야하면 instat field로 만드러야댐 

인스턴스 변수 두 개의 계산 결과를 저장할 수 있는 result 변수 준비   
result (<-non static 필드변경)
-------------------
plus()
Calculator c1 = new Calculator();
인스턴스 = Calculator 설계도에 따라 생성한 변수들 
Calculator c1
설계도에 따라 생성한 Calculator 
주소를 담는 c1 은 레퍼런스임
private static int result = 0;
에서
private int result = 0;
로 수정. 
new Calculator()로 인스턴스변수 생성해야함 
Calculator  c2 = new Calculator();

static 필드는 클래스가 로딩될때 메서드에리어에 저절로 생성.
non static 필드는 new 명령어를 사용해야만 heap에 생성됨.
private static int result = 0; 스태틱 변수
private int result = 0; 논스태틱 변수 
  public static int getResult(Calculator c) {
    return c.result;
  } 
에 따라 무조건 result가 하나씩 생김 (static 이어서)
plus(Calculator c, int a) {
 c.result = a }
c는 인스턴스 주소임. 

 

인스턴스필드+스태틱메서드   인스턴스필드 + 인스턴스메서드(인스턴스 변수를 보다 쉽게 다룰 수 있도록 만들어진 문법)
Calculaotr c1 = new Calculator();
Calculator.plus(c1, 2);
c1 = 메서드를 호출할 때 마다 메서드가 사용하고 있는 result변수가 있는 인스턴스의 주소를 파라미터로 넘겨야 한다. 
=>문법 간결화(자연스러움)
c1.plus(2); 

c1 = 인스턴스의 주소를 메서드 이름 앞쪽에 넘긴다. 
 

 

this 생략하면 컴파일러가 알아서 붙여서 컴파일

메서드를 호출할 때 인스턴스(주소)를 받아서 넣음 

this 생략하면 컴파일러가 알아서 불러와서 컴파일함. (생략가능)

instance 메서드에는 this 변수가 내장되어 있음

(Calculator this; 이 라인을 자동으로 추가함. = 외부에서 넘겨준 인스턴스 주소)

static 메서드는 this 변수가 내장되어 있지 않음 

 

Calculator c = new Calculator ();
인스턴스 생성 : 인스턴스 필드(변수) 생성, (메서드가 아님 ! )
- result 인스턴스 생성, Calculator 클래스가 생기는 게 아님
c에 result 의 주소가 들어감 
public class Calculator {

  private int result = 0;
  public void plus(int a) {
    this.result += a;
  }
c.plus(100);
plus = operator(연산자)
c, 100 = operand(피연산자)
Object Oreinted Analaysis Design : OOAD 객체지향분석설계 상 명칭
 

JVM stack(인스턴스변수) 과 heap에는 로컬변수만 존재 

메서드들은 멤서드 에리어에 생김 

 

 static 블럭 안에서는 static 이 아닌 변수를 사용할 수 없다. 

■ int result = 0; // 로컬 변수는 반드시 초기값을 지정해야함 

 

 

프로젝트 폴더

myapp:  root 프로젝트 

app : 메인 프로젝트

sub1 : 서브 

sub2 : 서브

 

자바 이후부터 패키지임. 

 

 

 

 

 

 

 

 

 "modifier"  // 한정자 제한자 변경자

pakcage privte, protected, public

private : result 값을 다른 파일에서 변경할 수 없게 제한해버림.

 

 

 

● import bitcamp.util.Calculator;
//컴파일러야 Calculator 만나면 bitcamp.util을 앞에 붙여라~ Calculator 컴파일 하라는 거 아니다 ~ 

 

 

 

 

 

 

 

 

 


오후 수업 

// 1) 낱개의 변수 사용
// 2) 낱개의 변수 재사용
// 3) 배열 사용
// 4) 클래스를 이용하여 데이터 타입 정의(중첩클래스; 로컬 클래스)
// 5) 출력 기능을 별도의 메서드로 분리(중첩클래스; 스태틱 중첩 클래스) 
// 6) 합계 및 평균을 계산하는 기능을 메서드로 분리
// 7) GRASP 패턴: Information Expert(정보를 갖고 있는 클래스가 그 정보를 다룬다.)
// 8) 인스턴스 메서드 도입
// 9) 객체 생성이 번거롭고 복잡한 경우 메서드로 분리하는 것이 낫다..(디자인패턴: 팩토리 메서드)
// 10) GRASP 패턴: Information Expert(=> createScore()를 Score 클래스로 이동)
// 11) 생성자 도입: 인스턴스 변수를 보다 쉽게 초기화 시키기 
// 12) 클래스를 유지보수 하기 쉽게 별도 소스 파일로 분리 
// 13) 클래스를 유지보수 하기 쉽게 패키지로 분류(import, public )
// 14) 외부 접근 차단과 값 꺼내기. private& getter
// 15) 프로그래밍의 일관성을 위해 보통 다른 필드에 대해서도 getter를 만들고 사용한다. 
// 16) 필드의 직접 접근을 막고 setter를 정의하는 이유 
// 17) 필드의 직접 접근을 막기: 인스턴스 변수에 무효한 값이 저장되지 않게 하기 위해
//     =>getter 정의: 값을 꺼내기 위해 
//     =>setter 정의: 값을 변경할 때 사용. 단 유효한 값을 저장하도록 통제한다. 

1. 1명의 성적 : 낱개의 변수사용

2. 여러 명의 성적 : 낱개의 변수 재 사용 

3. 여러 명의 성적2: 배열 사용 , 반복문으로 출력

4. 클래스를 이용하여 데이터 타입 정의 

인스턴스는 재사용 하지말고 레퍼런스는 재사용 가능 

s = new Score(); 새 레퍼런스 생성. 이름은 기존 과 같음

5. 출력 기능을 별도의 메서드로 분리

4 코드에서 아래와 같이 메서드 추가하고 수정
4에서 ,, 클래스를 바깥으로 빼야함

6. 합과 평균을 메서드로 분리

 

7. GRASP 패턴: Information Expert(정보 전문가): 정보를 갖고 있는 클래스가 그 정보를 다룬다 

General Responsibility Assignment Software Patterns // 책임/역할, 할당/부여

GRASP 패턴 

1. Information Expert : 

2. Low Coupling : 관계를 적게 ,,, 

3. high Cohesin : 업무 집중도 높이기

 

compute는 성적을 다루는 메서드이기 때문에 메인이나 App에 두는 게 아니라 관련 메서드인 Score에 갖다둔다.

 

8. 인스턴스 메서드 도입 

9. 팩토링 ,,,

팩토리 메서드: creatScore

10.GRASP 패턴: Information Expert(=> createScore()를 관련 클래스인 Score 클래스로 이동)

createScore 이름을 클래스 이름이랑 겹치니까 create로 수정

11. 생성자 도입: 인스턴스 변수를 보다 쉽게 초기화 시키기 

생성자: 인스턴스를 생상한 직후 호출하는 메서드. 리턴 타입이 없음. 스코어 앞에 아무것도 없음.  클래스랑 이름 똑같아야함

기존 create는 삭제해버림. 생성자로 역할 다 하기때문에 ~

12.클래스를 유지보수 하기 쉽게 별도 소스 파일로 분리 

 

13.클래스를 유지보수 하기 쉽게 패키지로 분류

 

App에서 Score 쓰려면 Score내용을 public으로 수정해줘야함

클래스가 다른 패키지로 넘어가면 접근허용을 해줘야함. public하면 다른 곳에서 import 할 때 사용 가능 

14. 외부 접근 차단과 값 꺼내기. private& getter

임의로 접근했을때 값이 왜곡될수도 있기때문에 접근 못하게 막아줘야함. 

getter: private으로 접근이 막힌 변수의 값을 리턴해 주는 메서드 

카멜 표기법( 낙타등 표기법): 단어 조합해서 변수 명 지을 때 합성문자는 대문자 써주기

App 자바 파일도 수정 

15. 프로그래밍의 일관성을 위해 보통 다른 필드에 대해서도 getter를 만들고 사용한다. 

int, float이 private이기 때문에 나머지두 따라서,,

 

16. 필드의 직접 접근을 막고 setter를 정의하는 이유 


    scores[length++] = new Score("홍길동", 100, 100, 100);
    scores[length++] = new Score("임꺽정", 90, 90, 90);
    scores[length++] = new Score("유관순", 80, 80, 80);

    // 합계와 평균 계산이 끝난 후에 국어 점수를 변경한다면 
    //=> 국영수 점수와 합계, 평균 점수가 일치하지 않는 문제 발생  
    // => 데이터에 결함이 발생한다. 
    // 국영수 점수를 변경한 후에 compute를 호출하면 되지 않을까? 
    //=> 만약 개발자가 compute()호출하는 것을 잊어버리면 문제 발생 .. 
    // 만약 유효하지 않은 국영수 점수를 입력한다면  scores[0].kor = 7000;
    // => 도저히 막을 길 없음 
    scores[0].kor = 7000;

 

17.필드의 직접 접근을 막기: 인스턴스 변수에 무효한 값이 저장되지 않게 하기 위해

App.java

package bitcamp.test.step17;
import bitcamp.test.step17.vo.Score;

public class App {
  
  public static void main(String[] args) {

    final int MAX_SIZE = 10;
    Score[] scores = new Score[MAX_SIZE];
    int length = 0;

    //new Score(String, int, int, int)
    // => Score 설계도에 따라 인스턴스를 생성하라. 
    // => 생성한 후 String, int, int, int 파라미터 값을 받는 생성자를 호출해라 
    // => 이렇게 초기화시킨 인스턴스의 주소를 리턴해라. 
    scores[length++] = new Score("홍길동", 100, 100, 100);
    scores[length++] = new Score("임꺽정", 90, 90, 90);
    scores[length++] = new Score("유관순", 80, 80, 80);


    //scores[0].kor = 7000; 직접 접근 불가
    scores[0].setKor(70); // setter를 통해 값 변경 가능, 단, 유효한 점수일 경우만
    //scores[0].compute(); // 호출하는 것을 잊어버릴수 있기 때문에 setter에서 호출한다. 


    for (int i = 0; i < length; i++) {
      printScore(scores[i]);
    }
  }

  static void printScore(Score s) {
    System.out.printf("%s: 국어: %d, 영어: %d, 수학: %d,합계=%d, 평균=%.1f\n", 
      s.getName(), s.getKor(), s.getEng(), s.getMath(), s.getSum(), s.getAver());
  }
}

vo.Score.java

package bitcamp.test.step17.vo;

  public class Score {

    // 프로그래밍의 일관을 위해 그냥 막았다.
    private String name;

    //직접 접근을 허용했을 때 무효한 값을 저장할 수 있기 때문에 
    // private으로 접근을 막았다. 
    private int kor;
    private int eng;
    private int math;
    private int sum;
    private float aver;

    public Score(String name, int kor, int eng, int math){
      this.name = name;
      this.setKor(kor);
      this.setEng(eng);
      this.setMath(math);
    }

    public void compute() {
      this.sum = this.kor + this.eng + this.math;
      this.aver = this.sum / 3f;
    }

    //getter: private으로 접근이 막힌 변수의 값을 리턴해 주는 메서드 
    public int getSum() {
      return this.sum;
    }
    public float getAver(){
      return this.aver;
    }
    public String getName() {
      return this.name;
    }
    public int getKor() {
      return this.kor;
    }
    public int getEng() {
      return this.eng;
    }
    public int getMath() {
      return this.math;
    }

    public void setKor(int kor) {
      if (kor < 0 || kor > 100){
        return;
      }  
      this.kor=kor;
      this.compute();
    }

    public void setEng(int eng) {
      if (eng < 0 || eng > 100){
        return;
      } 
      this.eng=eng;
      this.compute();
    }

    public void setMath(int math) {
      if (math < 0 || math > 100) {
        return;
        }  
        this.math=math;
        this.compute();
      }

  }

숙제 : ex 01 - 04 예제 보기