예전 에 쓴 Design Pattern 의 글 입 니 다.
1. 순서
본 고 는 간단 한 다 열 정렬 의 예 에서 착안 하여 Design Pattern (디자인 모델) 의 목적, 분석 과 실천 을 간단명료 하 게 설명 하고 자 한다.
글 의 예 는 Compositor Pattern 과 Proxy Pattern 을 사용한다.
이 동시에 문장의 예 도 문제 (조건 조합 문제) 의 해결 방안 을 제공 했다.
2. 문제 의 도입
Design Pattern (디자인 모델) 의 목 표 는 공통 문제 의 변 하지 않 는 부분 과 변화 부분 을 분리 하 는 것 이다.변 하지 않 는 부분 은 Design Pattern (디자인 모델) 을 구성한다.이 점 은 프레임 워 크 와 비슷 하 다.
다음은 정렬 의 예 를 들 어 문제 의 변 하지 않 는 부분 을 어떻게 추출 하 는 지 설명 한다.
자바 류 레코드 에 field 1, field 2, field 3 등 필드 가 있다 고 가정 합 니 다.
public class Record{
public int field1;
public long field2;
public double filed3;
};
우 리 는 또 하나의 레코드 대상 의 배열 레코드 가 있다.우 리 는 이 배열 에 대해 서로 다른 조건 에 따라 정렬 해 야 한다.
우선, field 1 의 크기 에 따라 작은 것 부터 큰 것 까지 오름차 순 으로 정렬 합 니 다.
정렬 함 수 는 다음 과 같 습 니 다.
void sort(Record[] records){
for(int i =….){
for(int j=….){
if(records[i].field1 > records[j].field1)
// swap records[i] and records[j]
}
}
}
그 다음으로 field 2 의 크기 에 따라 작은 것 부터 큰 것 까지 오름차 순 서 를 매 긴 다.
void sort(Record[] records){
for(int i =….){
for(int j=….){
if(records[i].field2 > records[j].field2)
// swap records[i] and records[j]
}
}
}
또한, field 3 의 크기 에 따라 작은 것 부터 큰 것 까지 오름차 순 으로 정렬 합 니 다.
이런 요 구 는 너무 많아 서 우 리 는 중복 코드 를 너무 많이 썼 다.문제 의 변화 부분 은 조건 부분 (흑체 의 if 조건 판단 문) 만 판단 하 는 것 을 볼 수 있다.
우 리 는 Comparator 인 터 페 이 스 를 도입 하여 이 변화 하 는 부분 을 추출 할 수 있다.
public interface Comparator(){
public boolean greaterThan(Record a, Record b);
};
sort ( ):
void sort(Record[] records, Comparator compare){
for(int i =….){
for(int j=….){
if(compare.greaterThen(records[i], records[j]))
// swap records[i] and records[j]
}
}
}
이렇게 하면 첫 번 째 요구 에 대응 합 니 다. records 배열 은 field 1 의 크기 에 따라 정렬 합 니 다.
우 리 는 Comparator 인 터 페 이 스 를 실현 하 는 CompareByField 1 종 류 를 만 들 수 있다.
public class CompareByField1 implements Comparator{
public boolean greaterThan(Record a, Record b){
if(a.filed1 > b.filed1){
return ture;
}
return false;
}
}
sort 함수 호출: sort (records, new CompareByField 1 ();
이렇게 하면 첫 번 째 요구 에 대응 합 니 다. records 배열 은 field 2 의 크기 에 따라 정렬 합 니 다.
우 리 는 Comparator 인 터 페 이 스 를 실현 하 는 CompareByField 2 종 류 를 만 들 수 있다.
public class CompareByField2 implements Comparator{
public boolean greaterThan(Record a, Record b){
if(a.filed2 > b.filed2){
return ture;
}
return false;
}
}
sort 함수 호출: sort (records, new CompareByField 2 ();
C + + STL 의 명칭 에 따 르 면 이곳 의 sort 는 알고리즘 (Algorithm), records 는 용기 (집합), Comparator 는 함수 대상 (Function Object) 이 라 고 부른다.
JDK 의 java. util. collections 류 의 sort 방법 과 java. util. Comparator 인 터 페 이 스 는 이러한 사고방식 에 따라 설계 되 었 다.sort 와 Comparator 를 어떻게 활용 하여 다 열 정렬 문 제 를 해결 하 는 지 살 펴 보 자.
3. 다 열 정렬 문제
3.1 정렬 조건 의 수량
우 리 는 SQL 문 구 는 강력 한 정렬 기능 을 실현 할 수 있 고 서로 다른 필드 의 배열 에 따라 정렬 할 수 있 으 며 오름차, 내림차 순 으로 정렬 할 수 있다 는 것 을 알 고 있다.예 를 들 어 아래 의 문구.
order by field1 asc, field2 asc, field3 desc。
이 정렬 조건 은 field 1 의 오름차 순, field 2 의 오름차 순, field 3 의 내림차 순 으로 정렬 됩 니 다.
앞 에 있 는 필드 는 비교적 높 은 우선 순위 가 있 습 니 다.
예 를 들 어 두 개의 기록 A 와 B 는 다음 과 같은 조건 을 만족시킨다. (1) A. field 1 > B. field 1, (2) A. field 2 < B. field 2.
이때 order by field 1, field 2 문장 으로 정렬 하면 A > B.
상기 조건 중의 (1) A. field 1 > B. field 1 이 A. field 1 = = B. field 1 로 변 하면.이때 조건 (2) 이 작용 한다.이때, A < B.
자바 에서 이런 유연 하고 강력 한 순 서 를 어떻게 실현 하 는 지 살 펴 보 자.
우 리 는 여전히 상기 절의 기록 류 를 예 로 들 었 다.Record 류 는 세 개의 필드 가 있 습 니 다. 몇 가지 가능 한 정렬 조건 이 있 는 지 살 펴 보 겠 습 니 다.
(1) field 1 에 따라 정렬 합 니 다.(2) field 2 로 정렬 합 니 다.(3) field 3 에 따라 정렬 합 니 다.(4) field 1, field 2 로 정렬 합 니 다.(5) field 1 오름차 순 으로 field 2 내림차 순 으로 정렬...
각종 정렬 조건 의 배열 조합 은 대략 30 가지 가 있다.그리고 필드 개수 가 증가 함 에 따라 정렬 조건 의 개 수 는 멱급수 로 증가한다.
이전 절의 sort 와 Comparator 방법 에 따라 만약 에 우리 가 임의의 조건 에 따라 정렬 하 는 목적 을 달성 해 야 한다 면 우 리 는 모든 정렬 조건 에 Comparator 를 제공 해 야 한다. 우 리 는 30 개의 Comparator 류 가 필요 하 다.: -)
물론 우 리 는 이렇게 하지 않 을 것 이다. 우 리 는 이 문제 중의 똑 같은 중복 부분 을 계속 추출 하여 우리 의 해결 방안 을 최적화 시 킬 수 있다.
3.2 문제 분석
우 리 는 이 문제 에서 변화 하 는 부분 과 변 하지 않 는 부분 을 분석 할 것 이다.
위의 모든 정렬 조건 에서 변 하지 않 는 부분 은 3 부분 이 있 습 니 다. (1) A. field 1 과 B. field 1 의 비교, (2) A. field 2 와 B. field 2 의 비교, (3) A. field 3 와 B. field 3 의 비교;변화 하 는 부분 은 두 부분 이 있 는데 (1) 이 세 가지 비교 조건 의 임 의 조합 배열, (2) 오름차 와 내림차 가 있다.
이 분석 에 따 르 면 우 리 는 두 가지 유형, ReverseComparator 류 와 Composite Comparator 류 를 도입 했다.
Composite Comparator 클래스 는 필드 의 조합 배열 문 제 를 해결 하 는 데 사 용 됩 니 다.
ReverseComparator 클래스 는 필드 의 오름차, 내림차 문 제 를 해결 하 는 데 사 용 됩 니 다.
3.3 ReverseComparator 류 의 코드
import java.util.Comparator;
public class ReverseComparator implements Comparator{
/** the original comparator*/
private Comparator originalComparator = null;
/** constructor takes a comparator as parameter */
public ReverseComparator(Comparator comparator){
originalComparator = comparator;
}
/** reverse the result of the original comparator */
public int compare(Object o1, Object o2){
return - originalComparator.compare(o1, o2);
}
}
3.4 Composite Comparator 류 의 코드
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
public class CompositeComparator implements Comparator{
/** in the condition list, comparators' priority decrease from head to tail */
private List comparators = new LinkedList();
/** get the comparators, you can manipulate it as need.*/
public List getComparators(){
return comparators;
}
/** add a batch of comparators to the condition list */
public void addComparators(Comparator[] comparatorArray){
if(comparatorArray == null){
return;
}
for(int i = 0; i < comparatorArray.length; i++){
comparators.add(comparatorArray[i]);
}
}
/** compare by the priority */
public int compare(Object o1, Object o2){
for(Iterator iterator = comparators.iterator(); iterator.hasNext();){
Comparator comparator = (Comparator)iterator.next();
int result = comparator.compare(o1, o2);
if(result != 0){
return result;
}
}
return 0;
}
}
3.5 Comparator 의 조합 응용
이 절 은 위의 두 가지 용법 을 서술 한다.
앞의 정렬 문제 에 대응 하여 우 리 는 3 개의 Comparator 클래스 만 필요 합 니 다.
(1)Field1Comaprator;
(2)Field2Comaprator;
(3)Field3Comaprator。
이러한 Comparator 를 어떻게 조합 하여 서로 다른 정렬 조건 을 실현 하 는 지 예 를 들 어 설명 한다.
(1)order by field1, field2
CompoiComparator myComparator = new CompoiComparator();
myComparator. addComparators(
new Comparator[]{new Field1Comaprator (), new Field2Comaprator ()};
);
// records is a list of Record
Collections.sort(records, myComparator);
(2)order by field1 desc, field2
CompoiComparator myComparator = new CompoiComparator();
myComparator. addComparators(
new Comparator[]{
new ReverseComparator(new Field1Comaprator ()),
new Field2Comaprator ()};
);
// records is a list of Record
Collections.sort(records, myComparator);
여기 서 제공 하 는 ReverseComparator 류 와 Composite Comparator 류 는 모두 Decorator Pattern 을 사용 합 니 다.
Composite Comparator 류 는 Composite Pattern 이기 도 합 니 다.
4. 필터 조건 의 배열 조합
(shinwell 의 지적 에 감 사 드 립 니 다. 뒤의 코드 를 고 쳤 습 니 다)
여과 조건 문제 도 조건 조합 문제 의 범주 에 속한다.예 를 들 어 JDK 가 제공 하 는 java. io. File 류 는 파일 필터 방법 listFile (FileFilter) 을 제공 합 니 다. 사용 자 는 서로 다른 FileFilter 를 맞 춤 형 으로 설정 하여 서로 다른 필터 조건 을 실현 할 수 있 습 니 다. 예 를 들 어 파일 시간 이 특정한 범위 내 에 있 습 니 다.파일 접미사 이름, 파일 이름 이 특정한 패턴 에 부합 합 니 다.디 렉 터 리 인지 파일 인지 등등.
마찬가지 로 우 리 는 상기 해결 방법 을 응용 하여 유연 한 여과 조건 조합 을 실현 할 수 있다. 하나의 Composite Filter 류 의 임 의 조합 여과 조건 으로 하나의 ReverseFilter 류 를 배제 조건 으로 할 수 있다.
4.1 Composite Filter 류 의 코드
import java.io.FileFilter;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
public class CompositeFilter implements FileFilter {
/** in the filter list, every condition should be met. */
private List filters = new LinkedList();
/** get the filters, you can manipulate it as need.*/
public List getFilters(){
return filters;
}
/** add a batch of filters to the condition list */
public void addFilters(FileFilter[] filterArray){
if(filterArray == null){
return;
}
for(int i = 0; i < filterArray.length; i++){
filters.add(filterArray[i]);
}
}
/** must meet all the filter condition */
public boolean accept(File pathname) {
for(Iterator iterator = filters.iterator(); iterator.hasNext();){
FileFilter filter = (FileFilter)iterator.next();
boolean result = filter.accept(pathname);
// if any condition can not be met, return false.
if(result == false){
return false;
}
}
// all conditions are met, return true.
return true;
}
}
4.2 ReverseFilter 클래스 의 코드
import java.io.FileFilter;
import java.io.File;
public class ReverseFilter implements FileFilter {
/** the original filter*/
private FileFilter originalFilter = null;
/** constructor takes a filter as parameter */
public ReverseFilter(FileFilter filter){
originalFilter = filter;
}
/** must meet all the filter condition */
public boolean accept(File pathname) {
return !originalFilter.accept(pathname);
}
}
5. 총화
본 고 는 Design Pattern 의 분석 과 실천 을 서술 하고 조건 조합 문제 의 해결 방향 을 논술 했다.
Enjoy it. :-)
Thanks.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.