처음하는 페어프로그래밍(2024.04.05)

YJ·2024년 4월 5일
post-thumbnail

수업

6. 다형성

타입 변환

  • 클래스 자동 타입 변환
    개발자가 직접 명시해주지 않아도 자동으로 타입 변환이 일어나는 것
  • 클래스 강제 타입 변환
    개발자가 강제적으로 클래스의 타입을 명시하여 변환하는 것

클래스 강제 타입 변환 예시

public class Person {
    public static void main(String[] args) {
        Parent parent1 = new Parent();
        parent1.method();

        Child child = new Child();
        child.method();
//        child.metod();

        // 이렇게는 언제쓰지?
        Parent parent2 = new Child();
        parent2.method();
//        parent2.metod();
        // 별을 접는다는게 어떤 의미이지
        // 부모 타입 변수 안에 자식 객체를 넣을 경우 별 바깥 부분의 기능은 접힌다.

        Child child2 = (Child) parent2;
        child2.metod();
        // 접혀있으니까 알아서 펴줘야 하는거 아니야?
//        Child child2 = parent2;

        System.out.println(child2 instanceof Child);
    }
}


class Parent {
    void method() {
        System.out.println("부모 메소드");
    }
}

class Child extends Parent {
    @Override
    void method() {
        System.out.println("자식 메소드");
    }

    void metod() {
        System.out.println("별이 펴졌다");
    }
}

// 어노테이션은 한 묶음에만 영향력을 끼친다.
// 1. 컴파일러에게 Syntax 에러를 잡을 수 있다.

궁금한점: 왜 상위타입 변수명 = new 하위타입(); 사용하지?

위 방법으로 객체의 변수를 만들어 사용하면 다음과 같은 문제가 궁금하였다.

자식 클래스에만 정의된 메서드는 어떻게 사용하지?

오버로딩

오버로딩은 사실 생성자로부터
Q. 오버로딩이 필요한 이유가 무엇인가요?
Q. 오버로딩의 기준은 무엇인가요?
A. 오버로딩은 매개변수의 자료형/갯수/순서가 기준이다.
그러면, 반환타입은 달라도 될까?

반환타입이 다르면 오버로딩을 할 수 없다.

    int hi() {
        return 1;
    }

	// 오버로딩 가능
    int hi(int a) {
        return a;
    }

    // 오버로딩 에러
    double hi() {
        return 1.1;
    }

7. 추상 클래스와 인터페이스

추상 메소드

추상이란 무엇일까?
피카소 그림을 봐보자.

추상은 본질 을 뽑아내야 한다.
위 그림을 보면 사람 사진은 아니지만 본질을 뽑아서 그려서
대부분의 사람들은 이 그림을 보면 사람이라는 것을 알 수 있을 것이다.

구체 vs 추상
구체는 추상과 함께 따라다니는 개념이다.
추상을 통해 구체적인 것을 만들 수 있어야 한다.

추상 클래스

위 피카소 그림을 보자.
본질을 뽑아낸다고 해서 객체를 뽑아 낼 수 있을까?
저 그림을 통해 본질을 뽑은 것을 객체로 만들면 무서울 것이다.

추상 클래스는 추상 메서드가 포함된 클래스이다.
이 클래스를 통해서 객체 를 만들 수는 없는 것 이다.
그러면,
추상 클래스를 왜 쓸까?
사용하는 이유는 다음과 같다.

  • 자식 클래스들 간 공통적인 필드와 메소드 이름 및 구현 내용 통일
  • 반드시 구현해야하는 메소드 선언함으로써 공통 규격 제공

추상 메소드가 1개 이상 포함되어 있으면 반드시 추상 클래스로 선언되어야 한다. O
추상 클래스로 선언되어 있으면 반드시 추상 메소드가 1개 이상 포함되어야 한다. X

인터페이스

예를 들어, 인터페이스를 구현한 구현 클래스는
구현 클래스가 수정되더라도 우리가 사용하는 경우는 똑같다.
이는 모듈화 가 잘 되어 있다.
즉, 코드 분리가 잘 되어있다는 것이다.
이를 통해 코드 수정 범위가 축소된다.

장점
1. 코드 분리가 잘 되어있으면 유지보수가 편하다.
2. 보안 안정성에 좋다.

8. 클린코드와 리팩터링

리팩터링
설계하는 리팩터링
코드 리팩터링

인증된 툴 => IDE

페어 프로그래밍

들어가기 전..

프디아 교육 Java 수업 시간에 페어프로그래밍을 진행했다. 처음 들었을때는 '페어프로그래밍이 뭐지?' 라는 생각이 들었던 것 같다. 이후 강사님께 페어프로그래밍에 대해 설명을 듣고, 회사에서 진행한다고 생각하며 진지하게 진행해보았다. 처음한 경험인지라 이를 글로 남겨보고자 한다.

첫 페어프로그래밍 과제는 버블 정렬을 구현하는 것이었다. 페어프로그래밍을 진행하기 전에 어떠한 것을 느낄지, 짝에게 어떠한 것을 배울 수 있을지 고민해보았다.

이번 페어프로그래밍의 목적은 대부분의 수강생들이 첫 페어프로그래밍을 진행하는 것이었기에, 상대방의 의견을 존중하고 배려하며 진행해 보는 것이었다. 이런 기회를 우수한 실력을 가진 짝과 함께 진행할 수 있다는 것에 감사하였다. 또한, 회사에 입사하기 전에 이러한 경험들을 미리 겪어봄으로써 입사 후에 회사에 적용을 해볼 기회가 될 수 있을 것이라는 생각이 들었다.

페어 프로그래밍

페어 프로그래밍은 애자일 방법론 중 하나로써 하나의 컴퓨터를 두고 두 사람의 프로그래머가 작업하는 방법이다. 두 사람의 역할은 드라이버와 네비게이터로 나뉜다.

느낀점

40분 정도 시간이 배치되어, 10분씩 번갈아가며 네비게이터와 드라이버의 역할을 진행하였다.
각 역할에 따라 느낀점이 달라 역할 별로 구분하여 느낀점을 작성해보겠다.

네비게이터
처음 네비게이터 역할에 대해 강사님께 들었을 때는 다음과 같은 것이 해당 역할에 필요하다고 생각이 들었다.
개발할 것에 대한 이해가 있어 한다.
구조를 어떻게 짤지 고민해야 한다.
어떻게 드라이버를 이끌어야 할지.
다행히 버블 정렬 네비게이터 역할을 맡기 전에, 버블 정렬에 대해 복습을 한 상태여서 프로그램에 대한 이해는 갖추어 놓았다.
그러나 역할을 진행하면서 어려웠던 부분들이 많았다.
개발의 흐름을 구성해주고 말로 상대방을 이끌어줘야하는데
상대방이 나의 의견을 수용할 수 있도록 풀어서 설명하는 부분에서 쉽지는 않았던 것 같다. 다음에 페어프로그래밍을 진행할 때는 조금 더 쉽게 드라이버에게 설명을 해드리는 것을 연습해야 할 것 같다.

드라이버
처음 맡아본 역할이라 단순히 네비게이터를 믿고 코드에 문법적인 오류가 없도록 가이드 해주시는데로 코드를 작성해본 것 같다.
이 역할에서는 두 가지를 느낀 것 같다.
첫 번째는, 내가 실시간으로 작성하는 코드를 타인에게 보여줌에 있어 약간의 긴장감이 느껴진다는 것이었다. 평소에 개발은 주로 혼자서 노트북 앞에 앉아 진행하곤 한다. 그러나 페어프로그래밍은 옆에 네비게이터가 앉아 같은 모니터를 바라보며 진행하는 지라 약간의 부담감이 생겼던 것 같다.
두 번째는, 이것이 라이브 코딩인가라는 생각이 들었다. 앞으로 지원할 회사들의 면접에서는 라이브 코딩도 진행할 것인데, 그 역시 페어프로그래밍과 비슷할 것 같다는 생각이 들었다. 그렇기에 이러한 경험치를 자주 축적해놓음으로써 나의 역량을 쌓아 올려야겠다는 생각이 들었다.

이번에 페어 프로그래밍으로 작성한 코드이다.

package pair;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

    public class week1 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        int[] arr = new int[n];

        for (int i = 0; i < n; i++) {
            arr[i] = Integer.parseInt(st.nextToken());
        }

        int temp;
        for (int i = n - 1; i >= 1; i--) {
            for (int j = 0; j < i; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }

        System.out.println(
                Arrays.stream(arr)
                .mapToObj(String::valueOf)
                .collect(Collectors.joining(" "))
        );
    }
}
profile
dev

0개의 댓글