Java 는 if else 대신 상태 모드(state pattern)를 어떻게 사용 합 니까?

12863 단어 자바ifelse
대부분의 개발 자 들 은 현재 if else 의 프로 세 스 구 조 를 사용 하고 있 으 며,jdon 의 banq 형님 이 쓴 글 을 본 적 이 있 으 며,command,op 모드 를 이용 하여 if else 프로 세 스 구 조 를 대체 하고 있다.그 때 는 잘 몰 랐 는데 요 며칠 동안'재 구성'제1장 영화 대여 사례 를 보면 서 감회 가 새 롭 습 니 다.if else 를 state pattern 으로 대체 하 는 이 유 를 말씀 드 리 겠 습 니 다.if else 를 대체 하 는 것 이 어떤 좋 은 점 이 있 는 지,그리고 if else 를 대체 하 는 상세 한 코드 를 알려 드 리 겠 습 니 다.본 고 는 jdon 의'아직도 if else 를 사용 하고 있 습 니까?'를 참고 한다.그리고 제1장.
먼저 우 리 는 영화 임대 과정 을 모방 하고 고객 이 영 화 를 빌 리 며 영 화 는 아동 영화,일반 영화,새 영화 로 나 뉜 다.영화 유형 및 임대 일수 에 따라 가격 이 각각 다 르 고(혜택 정도 에 따라)이용자 누적 포인트 가 다르다.
OK,지금 우 리 는 if else 로 표시 합 니 다.

 package com.qujingbo.movie;

 /**
 * <p/> Title:    
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:47:55
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
 public class Movie {

  //      
  public static int REGULAR = 1 ;
 
  //     
  public static int NEW_RELEASE = 2 ;
 
  //      
  public static int CHILDREN = 3 ;
 
  /**
  *         
  *
  * @param movieCode
  *     
  * @param days
  *     
  * @return       
  * @throws MovieException
  *           
  */
  public double getCharge( int movieCode, int days) throws MovieException {
  double result = 0 ;
  //    
  if (movieCode == Movie.REGULAR)
  //    2
  {
  result = 2 ;
  //         2 ,   
  if (days > 2 ) {
  result += (days - 2 ) * 1.5 ;
  }
  //     
  return result;
  }
  //      
  else if (movieCode == Movie.NEW_RELEASE) {
  //       ,   3
  return days * 3 ;
  }
  //    
  else if (movieCode == Movie.CHILDREN) {
  //     
  result = 1.5 ;
  //         3       
  if (days > 3 ) {
  result += (days - 3 ) * 1.5 ;
  }
  //         
  return result;
  } else
  throw new MovieException( "       " );
  }
 
  /**
  *         
  *
  * @param movieCode
  *     
  * @param days
  *     
  * @return       
  * @throws MovieException
  *           
  */
  public double getIntegral( int movieCode, int days) throws MovieException
  {
  //    
  if (movieCode == Movie.REGULAR)
  return days * 2 ;
  //      
  else if (movieCode == Movie.NEW_RELEASE)
  return days * 3 ;
  //    
  else if (movieCode == Movie.CHILDREN)
  return days * 1.5 ;
    else
     throw new MovieException( "       " );
 
  }
}

OK.현재 Movie 는 임대 수요 에 완전히 부합 되 고 getIntegral(int movieCode,int days)과 getCharge(int movieCode,int days)를 통 해 임대 포인트 와 임대 가격 을 얻 을 수 있 습 니 다.개폐 원칙 의 측면 에서 볼 때 새로운 영화 유형 을 추가 하려 면 getIntegral(int movieCode,int days)과 getCharge(int movieCode,int days)두 가지 방법 을 수정 해 야 한다.임대 가격,포인트 의 혜택 규칙 을 바 꾸 려 면 getIntegral(int movieCode,int days)과 getCharge(int movieCode,int days)방법 을 수정 해 야 한다.현재 로 서 는 세 가지 영화 유형 만 있 을 뿐 유지 보수 가 비교적 편리 하 다.한편,영화 의 유형 이 비교적 많 을 때 예 를 들 어 10 가지,100 가지 영화 유형 은 상상 할 수 없 는 유지 이다.
이제 if else 대신 state pattern 을 사용 해 보 자.아 날로 그 부터.

먼저 우 리 는 abstract class Price 를 영화 유형의 기본 클래스 로 만 들 었 다.기본 클래스 에는 두 개의 abstract 방법 이 포함 되 어 있 고 총 가격 getCharge(int days)를 얻 으 며 총 포인트 getIntegral(int days)방법 을 얻 으 며 abstract classPrice 의 세 가지 영화 유형 을 계승 하 는 어린이 영화 class Chileren Price,일반 영화 class Regular Price,최신 영화 class New Release Price 를 얻 었 다.getCharge(int days),getIntegral(int days)방법 을 각각 실현 하고 가격 을 계산 하 는 혜택 방안 과 포 인 트 를 기록 하 는 방안 을 실현 합 니 다.수정 방안 이 필요 할 때 우 리 는 특정한 영화 류 의 방법 에서 수정 에 대응 하면 된다.만약 에 영화 분 류 를 추가 할 때 우 리 는 하나의 실현 류 를 추가 하여 abstract class Price 류 를 실현 하면 OK.
class Movie 대표 영 화 는 Price 류 와 관련 되 고 setPrice(String movieClass)방법 은 한 공장 류 와 유사 하 며 movieClass 를 패키지 이름 으로 전달 하고 자바 반사 체제 로 구체 적 으로 movieClass 에 들 어 오 는 영화 유형 실현 류 를 예화 하면 우 리 는 이 몇 줄 의 코드 를 통 해 이 영화 유형의 가격 과 포 인 트 를 얻 을 수 있다.

 Movie regularMovie = new Movie();
regularMovie.setPrice(Movie.REGULAR);
System.out.println( "       10     " + regularMovie.getPrice().getCharge( 10 ));
System.out.println( "       10     " + regularMovie.getPrice().getIntegral( 10 ));
자세 한 코드 를 드 리 겠 습 니 다.
abstract class 가격 기본 클래스

package com.qujingbo.movie;

/**
 * <p/> Title:
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:48:22
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public abstract class Price {

 /**
  *                
  * 
  * @param days
  *       
  * @return       
  */
 public abstract double getCharge(int days);

 /**
  *               
  * 
  * @param days
  *       
  * @return       
  */
 public abstract double getIntegral(int days);

}

아동 영화 Children Price 류,abstract class Price 실현,아동 영화 임대 총가격 getCharge(int days)및 아동 영화 임대 포인트 getIntegral(int days)실현.

package com.qujingbo.movie;

/**
 * <p/> Title:       、    
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:49:04
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class ChildrenPrice extends Price {

 /**
  *          ,        :   
  */
 public double getIntegral(int days) {
  //         
  return days * 1.5;
 }

 /**
  *          
  */
 public double getCharge(int days) {
  //     
  double result = 1.5;
  //         3       
  if (days > 3) {
   result += (days - 3) * 1.5;
  }
  //         
  return result;
 }

}

일반 영화 RegularlPrice 류 는 abstract class Price 를 실현 하고 일반 영화 임대 총가격 getCharge(int days)와 일반 영화 임대 포인트 getIntegral(int days)을 실현 합 니 다.

package com.qujingbo.movie;

/**
 * <p/> Title:       、    
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:50:10
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class RegularlPrice extends Price {
 /**
  *          ,       
  */
 public double getIntegral(int days) {
  //         
  return days * 2;
 }

 /**
  *          
  */
 public double getCharge(int days) {
  //    2
  double result = 2;
  //         2 ,   
  if (days > 2) {
   result += (days - 2) * 1.5;
  }
  //     
  return result;
 }

}

최신 발표 편 NewReleasePrice 류,abstract class Price 실현,최신 발표 편 임대 총가격 getCharge(int days)및 최신 발표 편 임대 포인트 getIntegral(int days)실현.

package com.qujingbo.movie;

/**
 * <p/> Title:         、    
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:48:51
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class NewReleasePrice extends Price {
 /**
  *            ,         
  */
 public double getIntegral(int days) {
  //         
  return days * 3;
 }

 /**
  *            
  */
 public double getCharge(int days) {
  //       ,   3
  return days * 3;
 }

}

영화 Movie 류,setPrice(String movieClass)(공장)방법 은 자바 반사 체 제 를 통 해 movieClass(가방 명,클래스 명)류 를 실현 합 니 다.movieClass 같은 종류 가 없 으 면 MovieException 이상 을 던 집 니 다.

package com.qujingbo.movie;

/**
 * <p/> Title:   
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 15:47:55
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class Movie {
 //      
 public static String REGULAR = "com.qujingbo.movie.RegularlPrice";

 //     
 public static String NEW_RELEASE = "com.qujingbo.movie.NewReleasePrice";

 //      
 public static String CHILDREN = "com.qujingbo.movie.ChildrenPrice";

 private Price price;

 public Price getPrice() {
  return price;
 }

 /**
  *                 ,     
  * 
  * @param movieCode
  *       
  * @throws MovieException
  *              。
  */
 public void setPrice(String movieClass) throws MovieException {
  try {
   Class cls = Class.forName(movieClass);
   this.price = (Price) cls.newInstance();
  } catch (Exception e) {
   throw new MovieException("     ");
  }
 }
}

Movie Exception 소스 코드 를 드 립 니 다.

package com.qujingbo.movie;

/**
 * <p/> Title:     
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 19:21:08
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class MovieException extends Exception {
 public MovieException(String msg) {
  super(msg);
 }
}

다음은 고객 임대 영 화 를 모 의 방문 하 겠 습 니 다.

package com.qujingbo.movie;

/**
 * <p/> Title:
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 19:26:23
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
public class Customer {
 /**
  *   (    )
  * 
  * @throws MovieException
  *         ,    
  */
 public void consume() throws MovieException {
  //     
  Movie regularMovie = new Movie();
  regularMovie.setPrice(Movie.REGULAR);
  //       
  Movie newReleaseMovie = new Movie();
  newReleaseMovie.setPrice(Movie.NEW_RELEASE);
  //     
  Movie childrenMovie = new Movie();
  childrenMovie.setPrice(Movie.CHILDREN);

  System.out.println("      10    "
    + regularMovie.getPrice().getCharge(10));
  System.out.println("      10    "
    + newReleaseMovie.getPrice().getCharge(10));
  System.out.println("      10    "
    + childrenMovie.getPrice().getCharge(10));
  
  System.out.println("      10    "
    + regularMovie.getPrice().getIntegral(10));
  System.out.println("      10    "
    + newReleaseMovie.getPrice().getIntegral(10));
  System.out.println("      10    "
    + childrenMovie.getPrice().getIntegral(10));
  
  
 }
}

준 it 테스트 클래스 에서 class Customer 를 실행 하 는 consume()방법 을 쓰 십시오.

 package com.qujingbo.movie;

 import junit.framework.TestCase;

 /**
 * <p/> Title:junit   
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2006-10-14 19:32:57
 * </p>
 * 
 * @author EOMS    
 * @version 1.0
 */
 public class CustomerTest extends TestCase {

  private Customer customer = null ;

  protected void setUp() throws Exception {
   super .setUp();
  customer = new Customer();
 }

  protected void tearDown() throws Exception {
   super .tearDown();
 }

  /*
  * Test method for 'com.qujingbo.movie.Customer.consume()'
  */
  public void testConsume() {
   try {
   customer.consume();
  } catch (MovieException e) {
   System.out.println( "        " );
  }
 }

}

OK 。결 과 는:
일반 영화 대여 10 일 가격 14.0
최신 영화 임대 10 일 가격 30.0
아동 영화 대여 10 일 가격 12.0
일반 영화 대여 10 일 포인트 20.0
최신 영화 임대 10 일의 포인트 30.0
아동 영화 대여 10 일 포인트 15.0
마지막 으로 우리 가 OO 로 표시 한 임대 과정 은 완전 하지 않다.고객 이 반드시 한 편의 영화 만 임대 하 는 것 이 아니 라 여러 편의 영 화 를 임대 해 야 하기 때문에 우 리 는 Rental(임대 류)가 부족 하 다.다만 state pattern 이 if else 를 대체 한 다 는 것 을 설명 하기 위해 저 희 는 Rental(임대 류)를 추가 하지 않 았 습 니 다.참고 가 필요 하 시 면 제1장 을 찾 아 보 세 요.원본 다운로드 를 누 르 십시오.
자바 가 if else 대신 상태 모드(state pattern)를 어떻게 활용 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 가 if else 대신 상태 모드(state pattern)를 사용 하 는 지 에 대해 서 는 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기