C#/.NET(21): 캡슐화
캡슐화는 필수이다.
캡슐화는 객체 지향 프로그래밍의 기본 개념 중 하나이다.
캡슐화는 데이터와 그 데이터를 사용하는 메소드를 묶는 것을 의미하며, 캡슐화로 프로그래밍하면 논리 구조에 다양한 장점이 생긴다.
캡슐화를 연습하기 위해, 두 점 사이의 거리를 구하는 프로그램을 만들어보려고 한다.
먼저 두 점 사이의 거리를 구하려면, 아래 단계에 걸쳐 프로그래밍해야 한다.
- 좌표(x, y)를 저장하는 클래스
- 선분(시작점과 끝점)을 저장하는 클래스
- 선분의 길이를 구하고 그 값을 리턴하는 클래스
- 메인에서 선분으로 인스턴스를 생성하고 길이를 출력
코드는 아래와 같다. (*주석 처리된 코드는 내가 작성한 코드이다.)
[캡슐화 적용 전 - 예시 코드]
using System;
using static System.Console;
using static System.Math;
namespace encapsulation
{
class Point
{
public double x;
public double y;
}
class Line
{
public Point start;
public Point end;
}
internal class Program
{
static void Main(string[] args)
{
//var startPoint = new Point() { x = 5, y = 10 };
//var endPoint = new Point() { x = 0, y = 0 };
//var Line = new Line() { start = startPoint, end = endPoint };
var Line = new Line()
{
start = new Point() { x = 5, y = 10 },
end = new Point() { x = 0, y = 0 }
};
Write(Length(Line));
}
public float Length(Line line)
{
//double length = Sqrt(Pow((line.start.x - line.end.x), 2)
// + Pow((line.start.y - line.end.y), 2));
//return (float)length;
var xCoordinatesDiff = line.end.x - line.start.x;
var yCoordinatesDiff = line.end.y - line.start.y;
return (float)Sqrt(Pow(xCoordinatesDiff, 2) + Pow(yCoordinatesDiff, 2));
}
}
}
[데이터와 메소드 합치기 - 예시 코드]
아래 코드를 실행하면, 실행결과가 0으로 출력된다. 좌표 데이터가 제대로 전달되지 않는 것 같다.
using System;
using static System.Console;
using static System.Math;
namespace encapsulation
{
class Point
{
public double x;
public double y;
}
class Line
{
public Point start;
public Point end;
public float Length() // 데이터가 있는 곳으로 메소드 이동
{
var xCoordinatesDiff = end.x - start.x;
var yCoordinatesDiff = end.y - start.y;
return (float)Sqrt(Pow(xCoordinatesDiff, 2) + Pow(yCoordinatesDiff, 2));
}
}
internal class Program
{
static void Main(string[] args)
{
var Line = new Line()
{
start = new Point() { x = 5, y = 10 },
end = new Point() { x = 0, y = 0 }
};
Write(Line.Length());
}
}
}
[데이터를 사용하는 Class끼리 합치기 - 예시 코드]
using System;
using static System.Console;
using static System.Math;
namespace encapsulation
{
class Point
{
public double x;
public double y;
public Point(double _x, double _y) // constructor 추가
{
x = _x;
y = _y;
}
}
class Line
{
private Point start; // 정보은닉
private Point end; // 정보은닉
public Line(Point _start, Point _end) // constructor 추가
{
start = _start;
end = _end;
}
public float Length() // 데이터가 있는 곳으로 메소드 이동
{
var xCoordinatesDiff = end.x - start.x;
var yCoordinatesDiff = end.y - start.y;
return (float)Sqrt(Pow(xCoordinatesDiff, 2) + Pow(yCoordinatesDiff, 2));
}
}
internal class Program
{
static void Main(string[] args)
{
var Line = new Line(new Point(5, 10), new Point(0, 0));
Write(Line.Length());
}
}
}
캡슐화의 장점
데이터와 그 데이터를 사용하는 메소드를 합친다는 캡슐화는 개발자에게 논리적인 사고를 강요하는 것 같아, 막코딩에 길들여진 내가 적응하기는 쉽지 않을 것 같다…
하지만, 오류를 발견하고 문제가 발생했을 때, 쉽게 파악하려면 캡슐화와 논리적으로 코드를 짜려는 트레이닝이 필수적이다.
아래는 캡슐화의 장점을 정리한 내용이다.
- 데이터와 그 데이터를 사용하는 메소드를 합치기 때문에, 코드가 더욱 논리적이게 된다.
- 연산을 파악하기 쉽게 정리할 수 있다.
- 사용자로부터 데이터를 숨기거나 디테일한 연산 과정을 숨길 수 있다. (왜냐하면, 데이터와 연산을 수행하는 메소드가 다른 영역에 있으면, public을 남발하게 되지만 어차피 같은 곳에 묶여 있기 때문에 public 남발을 최소화할 수 있다.)
캡슐화와 정보 은닉은 같은걸까?
그렇지 않다.
캡슐화는 데이터와 그 데이터를 사용하는 메소드를 하나로 묶는 것이고, 정보 은닉은 멤버를 non-public 하게 만드는 것이다.
댓글남기기