[디딤돌 C++] 64. 직접 연관(DIRECTED ASSOCIATION) 관계

직접 연관 관계는 프로그램에서 가장 흔하게 볼 수 있는 관계로 명령을 내리는 개체와 명령을 받아 수행하는 개체의 관계입니다.

“고용자는 피 고용자에게 일을 시킬 수 있다.” 처럼 프로그램 세계에서는 매우 자연스러운 관계입니다. 목적 집단에서 목적을 달성하기 위해 상하 관계가 존재하는 것처럼 프로그램도 특정 목적을 수행하기 위한 코드 집합이어서 직접 연관 관계가 필요합니다.

특히 직접 연관 관계는 집합 관계나 구성 관계와 혼합 형태일 때도 많습니다. 예를 들어 회사 내부에 사원들이 있고 회사에서 특정 사원에게 일을 시킨다면 회사와 사원은 집합 관계이면서 직접 연관 관계입니다.

다음은 Company와 Worker 사이에 직접 연관 관계와 집합 관계가 형성할 때의 예제 코드입니다. Company에 Worker를 보관하는 저장소가 있어 컬렉션 역할을 수행하며 Company에 프로젝트를 수행하기 위해 컬렉션에 있는 Worker들에게 일을 시키는 형태입니다.

//Worker.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Worker
{
    string name;
public:
    Worker(string name);
    void Work();    
    string GetName()const;
};
//Worker.cpp
#include "Worker.h"
Worker::Worker(string name)
{
    this->name = name;
}
void Worker::Work()
{
    cout<<name<<" 일하다."<<endl;
}
string Worker::GetName()const
{
    return name;
}
//Company.h
#pragma once
#include "Worker.h"
class Company
{
    Worker **workers;
    size_t capacity;
    size_t count;
    size_t last_wi;//가장 최근에 일한 사원의 인덱스
public:
    Company(size_t capacity);
    ~Company(void);
    bool InWorker(Worker *worker);
    void DoProject(size_t size);
    void List()const;
    size_t GetCount()const;
    Worker *&operator[](size_t index);
};
//Company.cpp
#include "Company.h"

Company::Company(size_t capacity):capacity(capacity)
{
    workers = new Worker *[capacity];
    count = 0;
    last_wi=-1;
}
Company::~Company(void)
{
    delete[] workers;
}
bool Company::InWorker(Worker *worker)
{
    if(count>=capacity){    return false;    }
    workers[count] = worker;
    count++;
    return true;
}
void Company::DoProject(size_t size)
{
    cout<<"== 프로젝트 수행 =="<<endl;
    for(size_t i=0; i<size; i++)
    {
        last_wi= (last_wi+1)%count;
        workers[last_wi]->Work();
    }
}
void Company::List()const
{    
    cout<<"=== 직원 목록 ==="<<endl;
    for(size_t i=0;i<count;i++)
    {
        cout<<workers[i]->GetName()<<" ";
    }
    cout<<endl;
}
size_t Company::GetCount()const
{
    return count;
}
Worker *&Company::operator[](size_t index)
{
    if((index<0)||(index>=count))
    {
        throw "유효하지 않은 인덱스입니다.";
    }
    return workers[index];
}
//Program.cpp
#include "Company.h"
int main()
{
    Company *company = new Company(10);    
    
    company->InWorker(new Worker("홍길동"));
    company->InWorker(new Worker("강감찬"));
    company->InWorker(new Worker("을지문덕"));
    company->InWorker(new Worker("한석봉"));

    company->List();

    company->DoProject(2);
    company->DoProject(7);

    size_t count = company->GetCount();
    for(size_t i=0; i<count;++i)
    {
        delete (*company)[i];
    }
    delete company;
    return 0;
}

▷ 실행 결과

=== 직원 목록 ===
홍길동 강감찬 을지문덕 한석봉 
== 프로젝트 수행 ==
홍길동 일하다.
강감찬 일하다.
== 프로젝트 수행 ==
을지문덕 일하다.
한석봉 일하다.
홍길동 일하다.
강감찬 일하다.
을지문덕 일하다.
한석봉 일하다.
홍길동 일하다.