연습1
아래 코드는 id와 pwd값을 통해 계정의 유효성을 판단하는 코드이다.
public AuthResult authenticate(String id, String pwd) {
Member member = findOne(id);
if(member == null) return AuthResult.NO_MATCH;
if(member.getVefiricationEmailStatus() != 2) {
return AuthResult.NO_EMAIL_VERIFIED;
}
if(passwordEncoder.isPasswordValid(member.getPassword(), pwd, member.getId())) {
return AuthResult.SUCCESS;
}
return AuthResult.NO_MATCH;
}
위 코드는 캡슐화의 규칙인 Tell, Don't Ask가 적용된다. 데이터를 가져와서 판단하지 말고, 판단해달라고 부탁한다.
해당 관점에서 코드를 살펴보면 중앙의 getVerificationEmailStatus() 메서드를 수정할 수 있다. 이 메서드는 직접 데이터 값을 가져와서 판단하고 있다.
getVerificationEmailStatus() 메서드를 캡슐화한 결과는 아래와 같다.
public AuthResult authenticate(String id, String pwd) {
Member member = findOne(id);
if(member == null) return AuthResult.NO_MATCH;
if(member.isEmailVerifiedd()) {
return AuthResult.NO_EMAIL_VERIFIED;
}
if(passwordEncoder.isPasswordValid(member.getPassword(), pwd, member.getId())) {
return AuthResult.SUCCESS;
}
return AuthResult.NO_MATCH;
}
public class Member {
private int verificationEmailStatus;
public boolean isEmailVerifiedd() {
return verificationEmailStatus == 2;
}
}
연습2
아래 코드는 영화 렌털 정보를 담은 Rental 클래스와 렌털 되는 영화 정보를 담은 Movie 클래스이다.
public class Rental {
private Movie movie;
private int daysRented;
public int getFrequentRenterPoints() {
if(movie.getPriceCode() == Movie.NEW_RELEASE && daysRented > 1)
return 2;
else
return 1;
}
...
}
public class Movie {
public static int REGULAR = 0;
public static int NEW_RELEASE = 1;
private int priceCode;
public int getPriceCode() {
return priceCode;
}
...
}
위 코드는 캡슐화의 규칙인 Tell, Don't Ask가 적용된다. 데이터를 가져와서 판단하지 말고, 판단해달라고 부탁한다.
해당 관점에서 코드를 살펴보면 중앙의 getPriceCode() 메서드를 수정할 수 있다. 이 메서드는 직접 데이터 값을 가져와서 판단하고 있다.
getPriceCode() 메서드를 캡슐화한 결과는 아래와 같다.
public class Rental {
private Movie movie;
private int daysRented;
public int getFrequentRenterPoints() {
return movie.getFrequentRenterPoints(daysRented);
}
...
}
public class Movie {
public static int REGULAR = 0;
public static int NEW_RELEASE = 1;
private int priceCode;
public int getFrequentRenterPoints(int daysRented) {
if(priceCode == NEW_RELEASE && daysRented > 1)
return 2;
else
return 1;
}
...
}
연습3
아래 코드는 시간을 표시하는 프로퍼티를 가진 Timer 클래스와 이를 이용해 시작 시간과 종료 시간 등을 구하는 구현 코드이다.
Timer t = new Timer();
t.startTime = System.currentTimeMillis();
...
t.stopTime = System.currentTimeMillis();
long elapsedTime = t.stopTime - t.startTime;
// Timer 클래스
public class Timer {
public long startTime;
public long stopTime;
}
이 코드는 t.startTime, t.stopTime과 같이 클래스의 데이터를 직접 가져와서 사용하고 있는 전형적인 절차 지향적인 방식을 취하고 있다.
이를 캡슐화한 결과는 아래와 같다.
start(), stop(), elapsedTime() 메서드를 정의하여 캡슐화하였다.
Timer t = new Timer();
t.start();
...
t.stop();
long time = t.elapsedTime(MILLISECOND);
// Timer 클래스
public class Timer {
private long startTime;
private long stopTime;
public void start() {
this.startTime = System.currentTimeMillis();
}
public void stop() {
this.stopTime = System.currentTimeMillis();
}
public elapsedTime(TimeUnit unit) {
switch(unit) {
case MILLISECOND:
return stopTime - startTime;
...
}
}
}
연습4
아래 코드는 findByToken() 메서드로 특정 토큰과 관련된 member를 구하고 있다. 또한 이메일 인증 관련 처리를 하는 메서드가 정의되어 있다.
public void verifyEmail(String token) {
Member member = findByToken(token);
if(member == null) throw new BadTokenException();
if(member.getVerificationEmailStatus() == 2) {
throw new AlreadyVerifiedException();
}else{
member.setVerificationEmailStatus(2);
}
...
}
위 코드는 getVerificationEmailStatus()를 통해 데이터를 직접 가져오고, setVerificationEmailStatus(2)를 통해 데이터를 직접 변경하고 있다.
아래 코드는 verifyEmail() 메서드를 통해 원래 기능을 한 곳에 모두 수행할 수 있도록 캡슐화했다.
public void verifyEmail(String token) {
Member member = findByToken(token);
if(member == null) throw new BadTokenException();
member.verifyEmail();
...
}
public class Member {
private int verificationEmailStatus;
public void verifyEmail() {
if(isEmailVerified())
throw new AlreadyVerifiedExceptioin();
else
this.verificationEmailStatus = 2;
}
public boolean is EmailVerified() {
return verificationEmailStatus == 2;
}
}
참조
'Programming > 기초지식' 카테고리의 다른 글
[객체 지향] 상속보단 조립 (0) | 2021.10.22 |
---|---|
[객체 지향] 다형성과 추상화 (0) | 2021.10.22 |
[객체 지향] 캡슐화(Encapsulation) (0) | 2021.10.21 |
절차지향과 객체지향 (0) | 2021.10.21 |
URI 그리고 URL (0) | 2021.09.03 |