수색…


소개

꽤 중요한 변수를 가진 클래스가 있다고 가정하고 코드에서 다른 프로그래머가 설정 한 값을 받아 들일 수없는 값으로 설정했습니다. 코드가 코드에 오류를 가져 왔습니다. 솔루션으로, OOP에서 객체의 상태 (변수에 저장 됨)를 메소드를 통해서만 수정할 수 있습니다. 객체의 상태를 숨기고 객체 메소드를 통해 모든 상호 작용을 제공하는 것을 데이터 캡슐화라고합니다.

비고

변수를 private 로 표시하고 필요한 경우 public 변수를 숨기는 것보다 노출하는 것이 훨씬 쉽습니다.

캡슐화가 유용하지 않을 수도있는 한 가지 예외가 있습니다. "멍청한"데이터 구조 (변수를 보관하는 것이 유일한 목적의 클래스)입니다.

public class DumbData {
    public String name;
    public int timeStamp;
    public int value;
}

이 경우, 클래스의 인터페이스는 데이터를 보유하고있다.

final 로 표시된 변수는 설정 후에 변경할 수 없으므로 캡슐화를 위반하지 않고 public 으로 표시 될 수 있습니다.

불변량을 유지하기위한 캡슐화

클래스에는 인터페이스와 구현의 두 부분이 있습니다.

인터페이스는 클래스의 노출 된 기능입니다. public 메소드와 변수는 인터페이스의 일부입니다.

구현은 클래스의 내부 작동입니다. 다른 클래스는 클래스 구현에 대해 알 필요가 없습니다.

캡슐화는 해당 클래스의 모든 사용자로부터 클래스의 구현을 숨기는 관행을 말합니다. 이것은 클래스가 내부 상태에 대한 가정을하도록합니다.

예를 들어, 각도를 나타내는이 클래스를 가져옵니다.

public class Angle {
    
    private double angleInDegrees;
    private double angleInRadians;
    
    public static Angle angleFromDegrees(double degrees){
        Angle a = new Angle();
        a.angleInDegrees = degrees;
        a.angleInRadians = Math.PI*degrees/180;
        return a;
    }
    
    public static Angle angleFromRadians(double radians){
        Angle a = new Angle();
        a.angleInRadians = radians;
        a.angleInDegrees = radians*180/Math.PI;
        return a;
    }
    
    public double getDegrees(){
        return angleInDegrees;
    }
    
    public double getRadians(){
        return angleInRadians;
    }
    
    public void setDegrees(double degrees){
        this.angleInDegrees = degrees;
        this.angleInRadians = Math.PI*degrees/180;
    }
    
    public void setRadians(double radians){
        this.angleInRadians = radians;
        this.angleInDegrees = radians*180/Math.PI;
    }
    private Angle(){}
}

이 클래스는 기본 가정 (또는 불변성 )에 의존합니다. angleInDegrees와 angleInRadians은 항상 동기화 됩니다. 반원들이 공개 일 경우 두 각도 표현이 서로 연관되어 있다는 보장은 없다.

커플 링을 줄이기위한 캡슐화

캡슐화를 사용하면 클래스를 호출하는 코드에 영향을주지 않고 클래스를 내부적으로 변경할 수 있습니다. 이것은 커플 링 을 줄이거 나 주어진 클래스가 다른 클래스의 구현에 의존하는 정도를 줄입니다.

예를 들어, 앞의 예제에서 Angle 클래스의 구현을 변경해 보겠습니다.

public class Angle {
    
    private double angleInDegrees;
    
    public static Angle angleFromDegrees(double degrees){
        Angle a = new Angle();
        a.angleInDegrees = degrees;
        return a;
    }
    
    public static Angle angleFromRadians(double radians){
        Angle a = new Angle();
        a.angleInDegrees = radians*180/Math.PI;
        return a;
    }
    
    public double getDegrees(){
        return angleInDegrees;
    }
    
    public double getRadians(){
        return angleInDegrees*Math.PI / 180;
    }
    
    public void setDegrees(double degrees){
        this.angleInDegrees = degrees;
    }
    
    public void setRadians(double radians){
        this.angleInDegrees = radians*180/Math.PI;
    }

    private Angle(){}
}

이 클래스의 구현은, 각도의 1 표현만을 포함 해, 필요에 따라서 다른 각도를 계산하도록 (듯이) 변경되었습니다.

그러나 구현이 변경되었지만 인터페이스가 변경되지 않았습니다 . 호출 클래스가 angleInRadians 메서드에 액세스하는 데 의존하는 경우 새 버전의 Angle 을 사용하도록 호출 클래스를 변경해야합니다. 클래스를 호출하면 (자), 클래스의 내부 표현에 관해서는 안됩니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow