'추상화'란 것은, 어떤 기능을 가진 객체를 구현할때, 객체 외부에서는 그 기능의 정확한 묘사를 하지 않는 것입니다. 그 대신 그 기능의 '추상적 행위'를 묘사해야 합니다.
이를테면 다음과 같은 잠수함을 구현한다고 해 봅시다.
class Submarine
{
private int x; // x좌표
private int y; // y좌표
private int depth;// 깊이
public int GetX() { return x; }
public int SetX(int x) { this.x = x; }
...........
}
void Function(Submarine ship)
{
// 북쪽으로 이동
ship.SetY(ship.GetY() - 1);
// 수면으로 이동
if(ship.GetDepth() > 0)
ship.SetDepth(ship.GetDepth() - 1);
}
이런 식으로 해도 동작은 하겠죠. 하지만 이런 구현을 한다면 구태여 OOP 프로그램을 사용할 필요가 없습니다. 그냥 C로도 구현되는 수준이거든요. 오히려 C로 하면 저런 잡다한 멤버함수를 만들 필요도 없이 쉽게 끝납니다(하지만 그냥 C 프로그램에서도 이런 식의 프로그램은 좋지 않습니다*).
이것을 제대로 추상화를 구현한다면 이런 식이 되어야 합니다.
class Submarine
{
private int x; // x좌표
private int y; // y좌표
private int depth;// 깊이
public void ToEast() { ++x; }
public void ToWest() { --x; }
public void ToSouth() { ++y; }
public void ToNorth() { --y; }
public void Float()
{
if(depth > 0)
--depth;
}
public void Sink() { ++depth; }
}
void Function(Submarine ship)
{
// 북쪽으로 이동
ship.ToNorth();
// 수면으로 이동
ship.Float();
}
캡슐화(Capsulation)는 멤버변수에 직접 접근이 힘들 뿐, 실제 멤버변수가 뭐가 있는지 알 수는 있다는 점에서, 추상화는 캡슐화보다 한단계 더 진행한 개념이라고 볼 수 있죠.
만약
class Ocean
{
......
public bool IsReef(int x, int y) // 암초가 있는가
{
.....
}
}
class Submarine
{
private int x; // x좌표
private int y; // y좌표
private int depth;// 깊이
public int GetX() { return x; }
public int SetX(int x) { this.x = x; }
...........
}
void Function(Ocean ocean, Submarine ship)
{
// 북쪽으로 이동
ship.SetY(ship.GetY() - 1);
// 암초에 걸렸는지 체크
if(ocean.IsReef(ship.GetX(), ship.GetY())
ship.Destroyed();
}
이런 것은 '캡슐화'는 되었지만(x, y변수가 '캡슐화되었죠) '추상화'가 된 코드는 아닙니다. '추상화'를 시킨다면
class Ocean
{
......
public bool IsReef(int x, int y) // 암초가 있는가
{
.....
}
}
class Submarine
{
private int x; // x좌표
private int y; // y좌표
private int depth;// 깊이
public void ToEast() { ++x; }
public void ToWest() { --x; }
public void ToSouth() { ++y; }
public void ToNorth() { --y; }
public bool IsSafe(Ocean ocean)
{
if(ocean.IsReef(x, y)) // 암초에 걸렸으면
return false;
// 다른 상황 체크
// 모두 통과했으면 안전
return true;
}
...........
}
void Function(Ocean ocean, Submarine ship)
{
// 북쪽으로 이동
ship.ToNorth();
// 배가 안전한지 체크
if(ship.isSafe(ocean))
ship.Destroyed();
}
가 되어야 합니다.
* 위에서 저런 식의 코딩은 C에서도 좋지 않다고 했는데, C에서의 코딩은 다음과 같이 하는 것이 좋습니다.
struct Ocean
{
......
}
struct Submarine
{
int x; // x좌표
int y; // y좌표
int depth;// 깊이
}
void ToEast(Submarine ship) { ++ship.x; }
void ToWest(Submarine ship) { --ship.x; }
void ToSouth(Submarine ship) { ++ship.y; }
void ToNorth(Submarine ship) { --ship.y; }
bool IsSafe(Ocean ocean, Submarine ship)
{
if(ocean.IsReef(ship.x, ship.y)) // 암초에 걸렸으면
return false;
// 다른 상황 체크
// 모두 통과했으면 안전
return true;
}
void Function(Ocean ocean, Submarine ship)
{
// 북쪽으로 이동
ToNorth(ship);
// 배가 안전한지 체크
if(isSafe(ocean, ship))
Destroyed(ship);
}
댓글 없음:
댓글 쓰기