본문 바로가기
이직&취업/Java 기초 상식

캡슐화(Encapsulation)가 무엇이며, 정보은닉(Information Hiding)과 어떻게 다르지?

by journeylabs 2025. 4. 27.
728x90
반응형

목차

     

    캡슐화(Encapsulation)정보은닉(Information Hiding)은 객체지향 프로그래밍의 핵심 원칙으로, 코드의 안정성과 유지보수성을 높이는 데 필수적입니다. 이 글에서는 캡슐화와 정보은닉의 주요 개념, 특징, 차이점, 원리, 실무에서의 활용 사례, 장단점, 그리고 주의사항을 자세히 다뤄보겠습니다. 초보자부터 실무 개발자까지 쉽게 이해할 수 있도록 구성했으니, 캡슐화와 정보은닉의 모든 것을 마스터하고 싶다면 끝까지 읽어보세요!


    1. 캡슐화와 정보은닉이란? 주요 개념 및 용어

    캡슐화의 정의

    캡슐화는 객체의 데이터(속성)와 해당 데이터를 처리하는 메서드를 하나의 단위(클래스)로 묶고, 외부로부터 접근을 제한해 데이터의 무결성을 유지하는 객체지향 원칙입니다.

     

    정보은닉의 정의

    정보은닉은 객체의 내부 데이터와 구현 세부 사항을 외부로부터 숨기고, 필요한 경우에만 특정 인터페이스를 통해 접근하도록 하는 기법입니다. 캡슐화의 하위 개념으로 간주됩니다.

     

    주요 용어

    • 접근 제어자(Access Modifier): private, protected, public 등으로 클래스 멤버의 접근 범위를 지정.
    • 게터(Getter)/세터(Setter): private 필드에 접근하거나 수정하기 위한 메서드.
    • 인터페이스: 객체의 내부 구현을 숨기고, 외부와의 상호작용을 정의하는 계약.
    • 데이터 무결성: 객체의 데이터가 올바르고 일관된 상태를 유지하는 것.

    캡슐화와 정보은닉의 특징

    • 캡슐화:
      • 데이터와 메서드를 하나의 클래스에 묶음.
      • 접근 제어자를 통해 데이터 보호.
      • 객체의 책임과 독립성 강화.
    • 정보은닉:
      • 내부 구현 세부 사항을 외부에 노출하지 않음.
      • private 필드와 공용 메서드로 접근 제어.
      • 변경에 따른 외부 영향 최소화.

    캡슐화 vs 정보은닉 차이점

    항목 캡슐화  정보은닉
    정의 데이터와 메서드를 묶는 개념 내부 데이터를 숨기는 기법
    범위 전체적인 객체 설계 원칙 캡슐화의 하위 개념
    목표 데이터 무결성, 책임 분리 구현 세부 사항 보호
    구현 클래스, 접근 제어자, 메서드 private 필드, 게터/세터
    예시 set/get 메서드로 상태 관리 내부 데이터 직접 접근 금지

    2. 캡슐화와 정보은닉의 원리와 구조

    캡슐화와 정보 은닉이 없는 코드 예시

    public class Account {
        public int balance; // 외부에서 직접 접근 가능
    }
    • 외부에서 다음과 같이 직접 조작할 수 있어 버그와 예외가 발생할 가능성 ↑
    Account acc = new Account();
    acc.balance = -10000; // 잘못된 값 설정

    캡슐화의 원리

    캡슐화는 객체의 데이터와 동작을 하나의 클래스에 통합하고, 접근 제어자를 사용해 외부 접근을 제어합니다. 이를 통해 데이터 무결성을 유지하고, 객체 간 결합도를 낮춥니다.

     

    캡슐화 구현 예시

    public class BankAccount {
        private double balance; // 정보은닉: private 필드
    
        // 캡슐화: 데이터와 메서드 묶기
        public BankAccount(double initialBalance) {
            if (initialBalance >= 0) {
                this.balance = initialBalance;
            }
        }
    
        // 정보은닉: 게터/세터로 접근 제어
        public double getBalance() {
            return balance;
        }
    
        public void deposit(double amount) {
            if (amount > 0) {
                balance += amount;
            }
        }
    
        public void withdraw(double amount) {
            if (amount > 0 && balance >= amount) {
                balance -= amount;
            }
        }
    }
    • 설명: balance는 private으로 외부 접근 차단(정보은닉). deposit과 withdraw 메서드는 데이터 무결성을 유지하며 접근 제공(캡슐화). 생성자와 메서드는 객체의 책임을 정의.

    정보은닉의 원리

    정보은닉은 private 필드와 공용 메서드(게터/세터 또는 커스텀 메서드)를 사용해 내부 데이터를 보호합니다. 외부에서는 객체의 구현 세부 사항을 알 필요 없이 인터페이스만 사용합니다.

     

    정보은닉 구현 예시

    public class Employee {
        private String name;
        private int employeeId;
        private double salary; // 정보은닉: private 필드
    
        public Employee(String name, int employeeId, double salary) {
            this.name = name;
            this.employeeId = employeeId;
            this.salary = salary >= 0 ? salary : 0;
        }
    
        // 정보은닉: 제한된 접근 제공
        public String getName() {
            return name;
        }
    
        public int getEmployeeId() {
            return employeeId;
        }
    
        public void setSalary(double salary) {
            if (salary >= 0) {
                this.salary = salary;
            }
        }
    
        // 내부 구현 숨김
        public double calculateBonus() {
            return salary * 0.1; // 보너스 계산 로직은 외부에 노출되지 않음
        }
    }
    • 설명: salary는 private으로 외부 접근 차단. setSalary는 유효성 검사를 통해 데이터 무결성 유지. calculateBonus는 내부 로직을 숨기고 결과만 제공.

    구조 비교

    • 캡슐화: 클래스 전체를 설계하며, 데이터와 메서드를 하나의 단위로 묶음.
    • 정보은닉: 캡슐화의 일부로, 데이터와 구현 세부 사항을 숨기는 데 초점.

    3. 실무에서 캡슐화와 정보은닉 활용 사례

    캡슐화와 정보은닉은 Spring Framework와 같은 프레임워크에서 객체 설계와 데이터 보호에 광범위하게 적용됩니다.

    3.1. Spring Boot에서 DTO와 엔티티의 캡슐화

    Spring Boot에서는 DTO(Data Transfer Object)와 엔티티(Entity) 클래스에서 캡슐화와 정보은닉을 사용해 데이터 무결성을 유지합니다.

     

    예시: 엔티티 클래스

    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        private String username;
        private String password; // 정보은닉: private 필드
    
        // 기본 생성자 (JPA 요구사항)
        protected User() {}
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        // 정보은닉: 게터만 제공해 수정 불가
        public Long getId() {
            return id;
        }
    
        public String getUsername() {
            return username;
        }
    
        // 캡슐화: 비즈니스 로직 포함
        public void updatePassword(String newPassword) {
            if (newPassword != null && !newPassword.isEmpty()) {
                this.password = newPassword;
            }
        }
    }
    • 설명: User 엔티티는 private 필드로 데이터 보호(정보은닉). updatePassword 메서드는 유효성 검사를 통해 데이터 무결성 유지(캡슐화). protected 생성자는 JPA 요구사항을 충족.

    3.2. Spring Service 계층의 캡슐화

    Spring의 서비스 계층은 비즈니스 로직을 캡슐화하고, 내부 구현을 숨깁니다.

     

    예시: 서비스 클래스

    @Service
    public class UserService {
        private final UserRepository userRepository;
        private final PasswordEncoder passwordEncoder; // 정보은닉: private 필드
    
        @Autowired
        public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
            this.userRepository = userRepository;
            this.passwordEncoder = passwordEncoder;
        }
    
        // 캡슐화: 비즈니스 로직 포함
        public User registerUser(String username, String password) {
            String encodedPassword = passwordEncoder.encode(password);
            User user = new User(username, encodedPassword);
            return userRepository.save(user);
        }
    
        // 정보은닉: 내부 구현 숨김
        public boolean validateUser(String username, String password) {
            User user = userRepository.findByUsername(username);
            return user != null && passwordEncoder.matches(password, user.getPassword());
        }
    }
    • 설명: UserService는 private 필드로 의존성을 관리(정보은닉). registerUser와 validateUser는 비즈니스 로직을 캡슐화하고, 내부 구현(passwordEncoder)을 숨김.

    3.3. Spring Security에서의 정보은닉

    Spring Security는 사용자 인증 정보를 캡슐화하고, 민감한 데이터를 숨깁니다.

    public class CustomUserDetails implements UserDetails {
        private final String username;
        private final String password;
        private final List<GrantedAuthority> authorities;
    
        public CustomUserDetails(User user) {
            this.username = user.getUsername();
            this.password = user.getPassword();
            this.authorities = Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER"));
        }
    
        @Override
        public String getUsername() {
            return username;
        }
    
        @Override
        public String getPassword() {
            return password;
        }
    
        @Override
        public Collection<? extends GrantedAuthority> getAuthorities() {
            return authorities;
        }
    
        // 정보은닉: 내부 구현 숨김
        @Override
        public boolean isAccountNonExpired() {
            return true;
        }
    
        @Override
        public boolean isAccountNonLocked() {
            return true;
        }
    }
    
    • 설명: CustomUserDetails는 사용자 데이터를 private 필드에 저장(정보은닉). UserDetails 인터페이스를 구현해 필요한 정보만 노출(캡슐화).

    4. 캡슐화와 정보은닉의 장점과 단점

    캡슐화의 장단점

    • 장점:
      1. 데이터 무결성: 유효성 검사를 통해 데이터 일관성 유지.
      2. 유지보수성: 내부 구현 변경이 외부에 영향을 최소화.
      3. 책임 분리: 객체가 자신의 데이터와 동작을 관리.
    • 단점:
      1. 복잡성 증가: 클래스 설계와 메서드 정의에 추가 노력 필요.
      2. 과도한 캡슐화: 지나친 제한은 코드 유연성 저하.

    정보은닉의 장단점

    • 장점:
      1. 보안성: 민감한 데이터와 구현 세부 사항 보호.
      2. 변경 용이성: 내부 로직 변경 시 외부 코드 수정 불필요.
      3. 모듈화: 인터페이스를 통한 명확한 상호작용.
    • 단점:
      1. 추가 코드: 게터/세터 또는 커스텀 메서드 작성 필요.
      2. 디버깅 어려움: 내부 구현이 숨겨져 문제 추적 복잡.

    주의사항

    • 적절한 접근 제어: 모든 필드를 private으로 설정하고, 필요한 경우에만 public 메서드 제공.
    • 불필요한 게터/세터 지양: 모든 필드에 게터/세터를 제공하면 정보은닉 위배.
    • 비즈니스 로직 포함: 게터/세터 대신 의미 있는 메서드로 캡슐화 강화.
    • 문서화: 숨겨진 구현의 동작을 Javadoc으로 명확히 설명.
    • 과도한 제한 피하기: 지나친 정보은닉은 협업과 확장성을 저해.

    5. 결론

    캡슐화는 "어떻게 구성할 것인가"에 대한 구조적 설계이며, 정보 은닉은 "무엇을 숨길 것인가"에 대한 접근 제어입니다.
    둘은 서로 보완적 관계이며, 객체지향의 핵심 개념이자 유지보수 가능한 코드의 기반입니다.

    객체지향 설계의 시작은 캡슐화에서, 안정성과 보안성은 정보 은닉에서 출발합니다.

     

    캡슐화정보은닉객체지향 프로그래밍에서 데이터 무결성, 보안, 유지보수성을 보장하는 핵심 원칙입니다. 캡슐화는 데이터와 메서드를 하나의 단위로 묶어 책임을 명확히 하고, 정보은닉은 내부 구현을 숨겨 외부 영향을 최소화합니다. Spring Framework에서는 엔티티, 서비스, Spring Security 등에서 캡슐화와 정보은닉을 활용해 안정적인 애플리케이션을 구축합니다. 적절한 접근 제어와 설계로 두 원칙을 효과적으로 적용하면 코드 품질을 크게 향상할 수 있습니다.

    이 글을 통해 캡슐화와 정보은닉의 차이부터 실무 활용까지 완벽히 이해하셨길 바랍니다. 객체지향 설계를 강화해 더 견고한 코드를 작성해보세요!

    728x90
    반응형