본문 바로가기
Everyday Study

2024.08.05 (월) { Concerns, 다형성(Polymorphism), 어그리게이션&컴포지션, UML Class Diagram }

by xogns93 2024. 8. 5.

Concerns

 

"Concerns"는 소프트웨어 개발에서 특정 관심사 또는 문제 영역을 의미합니다. 관심사는 시스템의 특정 부분 또는 기능과 관련된 모든 것을 포괄하는 개념입니다. 예를 들어, 보안, 데이터베이스 액세스, 사용자 인터페이스, 비즈니스 로직 등은 모두 개별적인 관심사로 볼 수 있습니다.

 


다형성(Polymorphism)

 

객체 지향 프로그래밍의 핵심 개념 중 하나로, 같은 인터페이스나 상위 클래스에서 정의된 메서드를 다양한 방법으로 구현하는 능력을 말합니다. 다형성은 코드의 유연성과 재사용성을 높이는 데 중요한 역할을 합니다.

 

다형성의 종류

  1. 컴파일 타임 다형성 (Compile-time Polymorphism)
  2. 런타임 다형성 (Runtime Polymorphism)

1. 컴파일 타임 다형성 (Compile-time Polymorphism)

컴파일 타임 다형성은 메서드 오버로딩과 연관이 있습니다. 동일한 메서드 이름을 가지지만 매개변수의 수나 타입이 다른 여러 메서드를 정의하는 것을 말합니다.

 

예시: 메서드 오버로딩

public class MathUtils {
    // 두 정수의 합을 계산하는 메서드
    public int add(int a, int b) {
        return a + b;
    }

    // 세 정수의 합을 계산하는 메서드
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // 두 실수의 합을 계산하는 메서드
    public double add(double a, double b) {
        return a + b;
    }
}

public class Main {
    public static void main(String[] args) {
        MathUtils math = new MathUtils();
        System.out.println(math.add(1, 2));        // 출력: 3
        System.out.println(math.add(1, 2, 3));     // 출력: 6
        System.out.println(math.add(1.5, 2.5));    // 출력: 4.0
    }
}

 

 

2. 런타임 다형성 (Runtime Polymorphism)

런타임 다형성은 메서드 오버라이딩과 연관이 있습니다. 상위 클래스의 메서드를 하위 클래스에서 재정의하여 구현합니다. 이는 상속과 인터페이스를 통해 이루어집니다.

예시: 메서드 오버라이딩

// Animal 추상 클래스
abstract class Animal {
    // 추상 메서드
    public abstract void makeSound();
}

// Dog 클래스
class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Woof");
    }
}

// Cat 클래스
class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        // Animal 타입의 배열 생성
        Animal[] animals = {new Dog(), new Cat()};

        // 각 동물의 소리를 출력
        for (Animal animal : animals) {
            animal.makeSound();  // 런타임 시점에서 실제 객체의 메서드가 호출됨
        }
    }
}

어그리게이션 (Aggregation)

 

어그리게이션(Aggregation)은 객체 지향 설계에서 클래스 간의 관계를 나타내는 방법 중 하나입니다. 이는 부분-전체 관계를 의미하며, 부분 객체(구성 요소)는 전체 객체(집합체)와 독립적으로 존재할 수 있습니다. 어그리게이션을 이해하는 가장 쉬운 방법은 "전체와 부분"의 관계로 보는 것입니다. 어그리게이션은 하나의 엔티티가 다른 여러 엔티티를 포함하는 관계를 나타냅니다. 이는 UML 다이어그램에서 약한 소유 관계(white diamond)로 표시됩니다. 어그리게이션은 부분과 전체의 관계를 나타내지만, 부분은 전체와 독립적으로 존재할 수 있습니다.

 

어그리게이션의 예

예시 1: 학교와 학생

  • 학교는 여러 학생을 포함합니다.
  • 학생은 특정 학교에 속하지만, 학교와 관계없이 존재할 수 있습니다. 예를 들어, 한 학교에서 다른 학교로 전학할 수 있습니다.
class Student {
    private String name;

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class School {
    private String name;
    private List<Student> students;

    public School(String name) {
        this.name = name;
        this.students = new ArrayList<>();
    }

    public void addStudent(Student student) {
        students.add(student);
    }

    public List<Student> getStudents() {
        return students;
    }

    public String getName() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        School school = new School("Springfield Elementary");
        Student student1 = new Student("Bart Simpson");
        Student student2 = new Student("Lisa Simpson");

        school.addStudent(student1);
        school.addStudent(student2);

        System.out.println(school.getName() + " has the following students:");
        for (Student student : school.getStudents()) {
            System.out.println(student.getName());
        }
    }
}

코드 설명

  • Student 클래스는 학생을 나타내며, 이름을 속성으로 가집니다.
  • School 클래스는 학교를 나타내며, 여러 학생을 포함하는 리스트를 가집니다.
  • Main 클래스에서 School 객체와 Student 객체를 생성하고, 학생을 학교에 추가합니다.
  • 학생은 학교에 속하지만, 학교와는 독립적으로 존재할 수 있습니다. 예를 들어, 학생이 다른 학교로 전학을 가도 학생 객체는 여전히 유효합니다.


컴포지션 (Composition)

 

컴포지션은 객체 지향 설계에서 두 객체 간의 "강한 소유" 관계를 나타내는 개념입니다. 여기서 한 객체는 다른 객체를 구성 요소로 포함하고 있으며, 포함된 객체는 포함하는 객체의 생명 주기에 종속됩니다. 즉, 포함된 객체는 포함하는 객체가 존재할 때만 존재할 수 있고, 포함하는 객체가 소멸되면 포함된 객체도 함께 소멸됩니다.

 

컴포지션의 예

예시 1: 자동차와 엔진

자동차는 엔진을 포함합니다. 엔진은 자동차가 존재할 때만 의미가 있으며, 자동차가 폐기되면 엔진도 함께 소멸됩니다.

class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

class Car {
    private String model;
    private Engine engine;

    public Car(String model, String engineType) {
        this.model = model;
        this.engine = new Engine(engineType);  // Car 객체가 Engine 객체를 포함
    }

    public String getModel() {
        return model;
    }

    public String getEngineType() {
        return engine.getType();
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car("Toyota Camry", "V6");
        System.out.println("Car model: " + car.getModel());
        System.out.println("Engine type: " + car.getEngineType());
    }
}

코드 설명

  • Engine 클래스는 엔진을 나타내며, 엔진 타입을 속성으로 가집니다.
  • Car 클래스는 자동차를 나타내며, 자동차 모델과 Engine 객체를 속성으로 가집니다.
  • Car 클래스의 생성자에서 Engine 객체를 생성하여 초기화합니다. 이는 Car 객체가 Engine 객체를 포함함을 의미합니다.
  • Main 클래스에서 Car 객체를 생성하고, 자동차 모델과 엔진 타입을 출력합니다.

 

어그리게이션과 컴포지션의 차이

 

어그리게이션과 컴포지션은 둘 다 부분-전체 관계를 나타내지만, 다음과 같은 차이점이 있습니다:

  • 어그리게이션: 부분 객체는 전체 객체와 독립적으로 존재할 수 있습니다. 예를 들어, 학생은 특정 학교에 속하지만 학교와 관계없이 존재할 수 있습니다.
  • 컴포지션: 부분 객체는 전체 객체에 강하게 결합되어 있으며, 전체 객체가 삭제되면 부분 객체도 함께 삭제됩니다. 예를 들어, 자동차는 엔진을 포함하지만, 자동차가 폐기되면 엔진도 더 이상 존재하지 않습니다.

1대다 관계 (One-to-Many)

 

1대다 관계는 하나의 객체가 여러 객체와 연관되는 관계를 나타냅니다. 이는 데이터베이스에서도 자주 사용되는 관계 유형입니다.

예시: 회사와 직원

회사는 여러 직원을 가질 수 있으며, 직원은 하나의 회사에만 속합니다.

class Employee {
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Company {
    private String name;
    private List<Employee> employees;

    public Company(String name) {
        this.name = name;
        this.employees = new ArrayList<>();
    }

    public void addEmployee(Employee employee) {
        employees.add(employee);
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public String getName() {
        return name;
    }
}

public class Main {
    public static void main(String[] args) {
        Company company = new Company("Tech Corp");
        Employee emp1 = new Employee("Alice");
        Employee emp2 = new Employee("Bob");

        company.addEmployee(emp1);
        company.addEmployee(emp2);

        System.out.println(company.getName() + " has the following employees:");
        for (Employee employee : company.getEmployees()) {
            System.out.println(employee.getName());
        }
    }
}

 

요약

  • 어그리게이션 (Aggregation): 약한 소유 관계로, 부분 객체가 전체 객체와 독립적으로 존재할 수 있습니다. 예: 학교와 학생.
  • 컴포지션 (Composition): 강한 소유 관계로, 부분 객체가 전체 객체의 생명 주기에 종속됩니다. 예: 자동차와 엔진.
  • 1대다 관계 (One-to-Many): 하나의 객체가 여러 객체와 연관되는 관계입니다. 예: 회사와 직원.

UML Class Diagram

 

UML 클래스 다이어그램(UML Class Diagram)은 시스템의 구조를 시각적으로 표현한 다이어그램입니다. 클래스 다이어그램은 클래스, 인터페이스, 관계(상속, 연관, 종속 등) 등을 포함하여 시스템의 정적인 구조를 나타냅니다. 이를 통해 시스템의 설계와 구조를 명확히 이해할 수 있습니다.

클래스 다이어그램의 구성 요소

  1. 클래스 (Class): 속성(필드)과 메서드(함수)를 포함합니다.
  2. 인터페이스 (Interface): 클래스와 유사하지만, 구현된 메서드가 없이 메서드의 시그니처만 정의됩니다.
  3. 관계 (Relationships):
    • 연관 관계 (Association): 클래스 간의 기본적인 관계.
    • 집합 관계 (Aggregation): 전체와 부분의 관계로, 부분이 독립적으로 존재할 수 있습니다.
    • 합성 관계 (Composition): 전체와 부분의 관계로, 부분이 전체에 종속됩니다.
    • 일반화 관계 (Generalization): 클래스 간의 상속 관계.
    • 의존 관계 (Dependency): 하나의 클래스가 다른 클래스를 사용하는 관계.

예시

여기서는 간단한 예시로 학교 시스템을 모델링해보겠습니다. 이 시스템에는 School, Student, Teacher 클래스가 있으며, Person이라는 상위 클래스를 가집니다.

 

클래스 다이어그램

+------------------+
|     Person       |
+------------------+
| -name: String    |
| -age: int        |
+------------------+
| +getName(): String|
| +getAge(): int   |
| +setName(String): void |
| +setAge(int): void |
+------------------+
          ^
          |
          |
  +------------------+
  |    Student       |
  +------------------+
  | -studentId: int  |
  +------------------+
  | +getStudentId(): int |
  | +setStudentId(int): void |
  +------------------+
          ^
          |
          |
  +------------------+
  |    Teacher       |
  +------------------+
  | -teacherId: int  |
  +------------------+
  | +getTeacherId(): int |
  | +setTeacherId(int): void |
  +------------------+
          ^
          |
          |
  +------------------+
  |     School       |
  +------------------+
  | -name: String    |
  | -students: List<Student> |
  | -teachers: List<Teacher> |
  +------------------+
  | +addStudent(Student): void |
  | +addTeacher(Teacher): void |
  | +getStudents(): List<Student> |
  | +getTeachers(): List<Teacher> |
  +------------------+

 


Implementation Perspective

그냥 우리가 작성하는 코드가 이것

 

"Implementation Perspective"는 UML 클래스 다이어그램을 설계할 때 시스템의 실제 구현과 관련된 세부 사항을 포함하는 관점을 의미합니다. 이는 시스템의 설계가 코드로 구현되는 방법을 나타내며, 클래스를 구현하는 속성, 메서드, 접근 제어자 등을 상세히 기술합니다.

Implementation Perspective의 구성 요소

  1. 클래스: 시스템의 구성 요소를 나타내며, 속성 및 메서드를 포함합니다.
  2. 속성: 클래스의 상태를 나타내는 변수입니다.
  3. 메서드: 클래스의 행동을 나타내는 함수입니다.
  4. 접근 제어자: 속성과 메서드의 접근 수준을 정의합니다 (public, private, protected).
  5. 연관 관계: 클래스 간의 관계를 나타내며, 실제 구현에서 클래스들이 어떻게 상호작용하는지를 보여줍니다.
  6. 상속 관계: 클래스 간의 계층 구조를 나타내며, 부모 클래스와 자식 클래스 간의 관계를 보여줍니다.
  7. 인터페이스: 클래스가 구현해야 하는 메서드를 정의하며, 실제 구현 클래스에서 메서드를 구현해야 합니다.
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

public class Student extends Person {
    private int studentId;

    public Student(String name, int age, int studentId) {
        super(name, age);
        this.studentId = studentId;
    }

    public int getStudentId() {
        return studentId;
    }

    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }
}

 

UML 다이어그램과 Implementation Perspective

위의 예시에서 UML 클래스 다이어그램은 각 클래스의 속성, 메서드, 그리고 클래스 간의 관계를 명확히 나타냅니다. 이는 시스템이 실제로 구현될 때 어떻게 동작할지에 대한 청사진을 제공하여, 개발자가 클래스와 객체 간의 상호작용을 이해하고 설계할 수 있도록 돕습니다.

요약

  • Implementation Perspective는 UML 클래스 다이어그램에서 시스템의 실제 구현과 관련된 세부 사항을 포함합니다.
  • 이를 통해 클래스 간의 관계와 내부 구조를 명확히 이해하고 설계할 수 있습니다.
  • UML 클래스 다이어그램은 클래스, 속성, 메서드, 접근 제어자, 연관 관계, 상속 관계 등을 포함하여 시스템의 정적인 구조를 시각적으로 표현합니다.