퇴근5분전

 객체지향을 항상 골똘히 생각하고 그에 맞게 코딩하고자 여러가지 생각을 하면서
머리속에 혼란스러워질 때가 있어서 정리해보려 함.

그중 하나로 대리자의 역할과 쓰임새에 대한 고민이 커졌다.
오늘 퇴근하면서 "버스에 내가 탔다!" 로 시작했다.

[버스에 내가 타는것]과 [버스가 나를 태운 것]으로 생각해보았다.
( 물론 위 문구는 몇번이나 생각해보았던 것이고 알맞게 정리 하였음. )

나만에 방식으로 몇번을 그림을 그려보는데 헷갈려서 그냥 집에 와서 코드소스로 만들었다.

아래 소스는 몇번 더 고민한끝에 수정된 소스이다. 
( 처음 적절하지 못한 사용에 대한 처리방법은 아래 주석처리가 되어있음. )

적절하지 못했던 방법부터 얘기를 풀어볼까낭.

버스를 코딩한답시고 타고, 내리고를 구현했고,  사람을 코딩한다고  타고, 내리고를 똑같이 코딩했었고
뭔가 맞지 않고 서로간에 연계가 이상했다.

처음 버스에 내가 탄것과, 버스가 나를 태운것과 처음 혼란스러웠다고 하면 바보 같겠지!
거창하게 말하자면 버스, 사람에 대한 두 객체설계를 했는데 그 과정에서 코드까지 풀어갈수 있게
나만에 스케치 방법에 착오로 인해 소스가 분명해지지 않고 맴도는 상태가 되어 더욱더 혼란스러워졌다.

해결책으로 생각해낸것이 주체를 정하는 것이었다.

버스 - 대리자 - 사람    이렇게 세개의 객체가 연결관계를 맺을 때 대리자는 버스와 사람간에 어떤 역할을
대신 해주는것이므로 방향을 지정해준다. 버스에서 사람으로 가는 메세지를 대신할것인지.
사람에서 버스로 가는 메세지를 대신 할것인지.

여기서 [버스 -> 사람] 버스가 사람을 태운다
          [사람 -> 버스] 사람이 버스에 탄다.

그렇게 생각하고 구현한고 테스트한게 아래 소스이다.

a.BusGetOn(bus.GetON);
a.BusGetOff(bus.GetOff);
bus.GetOn(b);
bus.GetOff(b);        

동일하게 버스에 태우고 내리고를 하게 되는 구문이다. 해석에 의문이 생길뿐이고...
몇가지 생각을 해보았다.

a가 버스에 타는 것.
버스에 a가 태워지는것,

이건 class 구문 내부를 보게 되었을 때...  아리까리함이 ... 처음엔 더 혼란스러웠다.

public class BusObject
{
         ...
        public void GetOn( PeopleObject  people)
        {
            // 사람이 버스에 탄다.
            if (!peoples.Contains(people))
            peoples.Add(people);
        }
}

public class PeopleObject {
        ...
        public void BusGetOn(_OnOut bus)
        {
            bus(this);  // 뭔지 모르고 자기를 던져 넣는다.
        }
}

 여기서 사람은 자기가 뭔가에 태워지게 되는데 뭔지 모르고 자기사진을 맡기게 되는 것.
 버스는 확실히 사람을 태우고 있고.

메서드 명이 뭔가 잘못된것이 보인다. 버스에 탄다 인데.. 버스를 받지 않고
대리자를 받고 있으니 어긋난 느낌이랄까?

 인자값으로 버스, 기차, 오토바이등의 상위 객체를 뽑아 탈것이라는 객체로 받는다면...
그것도 또 하나의 방법이 되겠지만... 지금 생각할것은 대리자의 쓰임새와 활용면을 고려해보려고 하니
좀더 고민하게 되었다.

그러다 찾아낸점이 사람이 타고, 내리고 라는 두개의 메세지가 존재하게 되는데, 현재 사용하고 있는 대리자가 있고  현재 타고, 내리고의 메서드는 동일하게

  bus(this);

이것만 있네?

좀더 고민을 통해 Do라는 메세지 1개로 절단 내버렸다.

대리자를 이용하니 이런게 되더라

Do라는 메세지하나로 버스에 타고, 내리고를 가리킬수 있게 되었다.

와우~~ 멋지다!


아래 보면 a.Do 라 해서 a에 Do라는 메세지로 어떤 행동을 지시할때 그 대상으로 bus.GetOn 이라는 대상을 제공한다.

a.Do( bus.GetOff );  a에게 행동하라고 지시하면서 버스에서 내려라! 라고 ... 되는것 같지 않은지?

나만 그렇게 보이는 건가?

bus에 GetOn 메세지를 날리면서 B를 제공한다.  
   GetOn은 "~에 태우다" 라는 뜻이공. GetOff는 "~에서 내리다."

대리자를 가지고 할수 있는 일 하나를 풀어보았는데 길다.
나도 읽을지 의문이 될정도로... 길게 썼넹.

이만~!

<< 이하 소스 전문 >>

     private void button1_Click(object sender, EventArgs e)
        {
            BusObject bus = new BusObject();

            PeopleObject a = new PeopleObject("A");
            PeopleObject b = new PeopleObject("B");
            PeopleObject c = new PeopleObject("C");

      // a.BusGetOn(bus.GetON);  // 처음 코딩했을 때.

            a.Do(bus.GetOn);   // a는 행동한다. 버스에 탔다.
            a.Do(bus.GetOff);   // a는 행동한다. 버스에서 내렸다.

            bus.GetOn(b);        // 버스에 b를 태우다.
            bus.GetOff(b);        // 버스에서 b를 내리다.

        }

    public delegate void _OnOff( PeopleObject  people);

    public class BusObject
    {
        List<PeopleObject> peoples = new List<PeopleObject>();

        public void GetOn( PeopleObject  people)
        {
            // 사람이 버스에 탄다.
            if (!peoples.Contains(people))
            peoples.Add(people);
        }

        public void GetOff(PeopleObject people)
        {
            if( peoples.Contains( people ) )
            peoples.Remove(people);
        }
    }

    public class PeopleObject
   
{
        string name = string.Empty;

        public PeopleObject( string _name)
        {
            name = _name;
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

     //public void BusGetOn(_OnOff bus)
        public void Do(_OnOut bus)
        {
            bus(this);
        }

        //public void BusGetOff(_OnOff bus)
        //{
        //    // 음 이건 자기가 뭐에서 내리는지도 모르고 내린다.
        //    bus(this);
        //}

    }