디자인 모델 에서 의 장식 기 모델 이 iOS 응용 개발 에서 의 실현 을 깊이 분석 하 다.
기본 실현
다음은 제 가 유형의 구조 도 를 다음 과 같이 보 여 드 리 겠 습 니 다.
위의 구조 도 를 간단하게 분석 해 보 자.Component 는 대상 인 터 페 이 스 를 정의 하고 이 대상 들 에 게 동적 으로 직책 을 추가 할 수 있다.Concrete Component 는 구체 적 인 대상 을 정의 하고 이 대상 에 게 직책 을 추가 할 수 있 습 니 다.Decorator,장식 추상 류 는 Component 를 계승 하여 외부 클래스 에서 Component 류 의 기능 을 확장 하지만 Component 에 있어 Decorator 의 존 재 를 알 필요 가 없다.Concrete Decorator 는 구체 적 인 장식 대상 으로 Component 에 직책 을 추가 하 는 기능 을 한다.
다음은 낡은 방식 입 니 다.저 는 가능 한 한 Objective C 가 실현 하 는 가장 간단 한 인 스 턴 스 코드 를 드 리 겠 습 니 다.먼저 이 코드 들 은 ARC 환경 에서 실행 되 기 때문에 메모리 누 출 을 일 으 킬 수 있 는 자원 에 대해 수 동 으로 방출 하 는 방식 을 사용 하지 않 았 다 는 점 을 주의 하 셔 야 합 니 다.
주의:본 논문 의 모든 코드 는 ARC 환경 에서 컴 파일 되 었 습 니 다.
컴 포 넌 트 클래스 인터페이스 파일
#import<Foundation/Foundation.h>
@interface Components :NSObject
-(void) Operation;
@end
컴 포 넌 트 클래스 구현 파일#import"Components.h"
@implementation Components
-(void)Operation{
return;
}
@end
Decorator 클래스 인터페이스 파일#import"Components.h"
@interface Decorator :Components{
@protected Components *components;
}
-(void)SetComponents:(Components*)component;
@end
Decorator 클래스 구현 파일#import"Decorator.h"
@implementation Decorator
-(void)SetComponents:(Components*)component{
components = component;
}
-(void)Operation{
if(components!=nil){
[components Operation];
}
}
@end
ConcreteComponent 클래스 인터페이스 파일
#import"Components.h"
@interface ConcreteComponent :Components
@end
Concrete Component 클래스 구현 파일
#import "ConcreteComponent.h"
@implementation ConcreteComponent
-(void)Operation{
NSLog(@" ");
}
@end
ConcreteDecoratorA 클래스 인터페이스 파일
#import "ConcreteDecoratorA.h"
#import "Decorator.h"
@interface ConcreteDecoratorA :Decorator
@end
ConcreteDecorator A 클래스 구현 파일#import"ConcreteDecoratorA.h"
@implementation ConcreteDecoratorA
-(void)Operation{
NSLog(@" A ");
[super Operation];
}
@end
ConcreteDecoratorB 클래스 인터페이스 파일#import "Decorator.h"
@interface ConcreteDecoratorB :Decorator
@end
ConcreteDecoratorB 클래스 구현 파일
#import "ConcreteDecoratorB.h"
@implementation ConcreteDecoratorB
-(void)Operation{
NSLog(@" B ");
[super Operation];
}
@end
주요 방법
#import <Foundation/Foundation.h>
#import "ConcreteComponent.h"
#import "ConcreteDecoratorA.h"
#import "ConcreteDecoratorB.h"
int main (int argc,const char* argv[])
{
@autoreleasepool{
ConcreteComponent *c = [[ConcreteComponent alloc]init];
ConcreteDecoratorA *d1 = [[ConcreteDecoratorA alloc]init];
ConcreteDecoratorB *d2 = [[ConcreteDecoratorB alloc]init];
[d1 SetComponents:c];
[d2 SetComponents:d1];
[d2 Operation];
}
return 0;
}
좋 습 니 다.위 에 보 여 줘 야 할 유형 입 니 다.문법 적 으로 모두 간단 합 니 다.중점 적 으로 말 할 필요 가 없습니다.주의해 야 할 것 은 하위 클래스 가 부모 클래스 를 호출 하 는 방법 에 대한 지식 입 니 다.즉,모든 대상 의 Operation 방법 을 호출 할 때 안에 코드 가[슈퍼 Operation]입 니 다.이 코드 구 조 는 매우 관건 적 이다.그 는 각 대상 간 의 Operation 방법의 전환 을 구성 하여 Components 류 대상 에 대한'장식'을 완성 했다.2.분류(Category)와 의뢰(Delegation)
Object-C 에는 두 가지 흔히 볼 수 있 는 실현 모델 이 있 습 니 다.분류(Category)와 의뢰(Delegation)입 니 다.
1.분류 카 테 고리
분 류 는 매우 강력 한 메커니즘 으로 이미 존재 하 는 클래스 에 새로운 방법 을 추가 할 수 있 으 며,그 에 게 하위 클래스 를 추가 할 필요 가 없다.새로운 방법 은 컴 파일 할 때 추 가 됩 니 다.이러한 확장 방법 처럼 정상적으로 실 행 될 수 있 습 니 다.하나의 장식 기 는 클래스 의 정의 와 조금 다른 것 은 장식 기 가 예화 되 지 않 기 때문에 확장 일 뿐이다.
알림:당신 의 클래스 확장 을 제외 하고 코코아 클래스 의 확장 추가 방법 도 사용 할 수 있 습 니 다.
분류 사용 방법:
현재 앨범 대상 이 있 습 니 다.폼 보기에 표시 해 야 합 니 다(table view):
앨범 제목 이 어디서 나 오 죠?앨범 은 모델 대상 일 뿐 이 데 이 터 를 표시 하면 관심 을 갖 지 않 습 니 다.이 를 위해 서 는 앨범 류 에 추가 코드 를 추가 해 야 하지만,이 종 류 를 직접 수정 하지 마 십시오.
앨범 에 분류(category)확장 자 를 추가 해 야 합 니 다.데이터 구 조 를 되 돌려 주 는 새로운 방법 을 정의 합 니 다.이 데이터 구 조 는 UITableViews 에서 쉽게 사용 할 수 있 습 니 다.
이 데이터 구 조 는 다음 과 같 습 니 다.
앨범 에 분 류 를 추가 합 니 다.내 비게 이 션 File\New\File...Object-C category 모드 를 선택 하 십시오.습관 적 으로 Object-C class 를 선택 하지 말고 Category 뒤에 TableRepresentation 을 입력 하고 Category to 뒤에 앨범 을 입력 하 십시오.
알림:이 새 파일 의 이름 에 주의 하 셨 습 니까?앨범+Table Representation 은 앨범 류 의 확장 임 을 설명 합 니 다.이 습관 은 매우 중요 하 다.첫째,이것 은 읽 기 쉽 기 때문이다.둘째,당신 이나 다른 사람 이 만 든 분류 와 충돌 하 는 것 을 방지 하기 때문이다.
앨범+TableRepresentation 을 열 고 다음 방법 원형 을 추가 합 니 다.
- (NSDictionary*)tr_tableRepresentation;
주의 하 세 요.이것 은 tr 입 니 다.이 분류 이름 의 줄 임 말 처럼 시작 하 는 방법 명:Table Representation.그 다음으로 이 습관 은 이 방법 이 다른 방법 과 이름 을 바 꾸 는 것 을 피 할 것 이다!
알림:분류(Category)성명 의 한 방법 이 원본 클래스 의 한 방법 과 이름 을 바 꾸 거나 같은 종류의 다른 분류 이름과 중복 되 거나(또는 부모 클래스)실행 중 일 때 어떤 방법 을 실행 해 야 할 지 모 릅 니 다.자신의 분류 에 있다 면 큰 문제 가 발생 할 수 없 지만 표준 코코아 나 코코아 터치 류 에 이 분류 방법 을 추가 하면 심각 한 문 제 를 일 으 킬 수 있다.
앨범+TableRepersentation.m 파일 을 열 고 다음 방법 을 추가 합 니 다.
- (NSDictionary*)tr_TableRepersentation
{
return @{@"titles":@[@"Artist", @"Album", @"Genre", @"Year"],
@"values":@[self.artist, self.title, self.genre, self.year]};
};
왜 이런 패턴 이 강 한 지 생각해 보 자.앨범 속성 을 직접 사용 할 수 있 습 니 다.
앨범 클래스 에 추가 되 었 지만 하위 클래스 는 아 닙 니 다.만약 하위 클래스 가 필요 하 다 면,너 도 마찬가지 로 이렇게 할 수 있다.
이러한 간단 한 추가,Album 류 의 데 이 터 는 UITableView 가 사용 할 수 있 는 데이터 구 조 를 되 돌려 주지 만 Album 의 코드 를 수정 할 필요 가 없습니다.
애플 은 기초 류 에서 분류 디자인 모델 을 대량으로 사용 했다.그들 이 어떻게 하 는 지 보 세 요.NSString.h 를 엽 니 다.@interface NSString 을 찾 으 면 세 가지 분 류 를 정의 합 니 다.NSString Extension Methods,NSExtended String Property ListParsing 과 NSSting Deprecated.코드 영화 에서 분 류 는 방법의 조직 성과 분 리 를 유지 하 는 데 도움 이 될 것 이다.
2.위임 위임
또 다른 장식 기의 디자인 모델 은 의뢰(Delegation)로 하나의 메커니즘 이 고 한 대상 이 다른 대상 을 대표 하거나 서로 협력 하 는 것 이다.예 를 들 어 UITableView 를 사용 할 때 그 중 하 나 는 반드시 실행 해 야 할 방법 입 니 다.tableView:numberOfRows InSection:.
UITable View 가 각 섹 션 에 몇 줄 이 있 는 지 알 고 싶 지 않 을 수도 있 습 니 다.이것 은 프로그램의 특성 입 니 다.따라서 각 섹 션 에 몇 줄 이 있 는 지 계산 하 는 작업 은 UITableView 의 의뢰(delegate)에 맡 겼 다.UITableView 클래스 가 표 시 된 데이터 에 의존 하지 않도록 합 니 다.
새 UITableView 를 만 들 었 을 때 다음 과 같은 설명 이 있 습 니 다.
UITableView 대상 의 작업 은 폼 보 기 를 표시 하 는 것 입 니 다.그러나 결국 이런 정 보 를 가지 고 있 지 않 은 정보 가 필요 하 다.그리고 그 의뢰 로 정 보 를 추가 하 는 메 시 지 를 보 냅 니 다.Object-C 에서 의뢰 모드 를 실현 합 니 다.하 나 는 프로 토 콜(protocol)을 통 해 선택 가능 하고 필수 적 인 방법 을 설명 할 수 있 습 니 다.잠시 후,이 튜 토리 얼 에서 프로 토 콜(protocols)을 덮어 씁 니 다.
하위 클래스 보다 더 쉬 워 보이 고 덮어 쓰 는 방법 이 필요 하지만,단일 클래스 라면 하위 클래스 만 만 들 수 있다 는 것 을 고려 해 보 세 요.한 대상 이 두 개 이상 의 대상 에 게 의뢰 하고 싶 을 때 하위 화 방법 은 실현 되 지 않 는 다.
알림:이것 은 매우 중요 한 모델 입 니 다.애플 은 UIKit 클래스 에서 이 방법 을 대량으로 사용 했다.UITableView,UITextView,UITextField,UIWebView,UIAlert,UIActionSheet,UICollection View,UIPickerView,UIGesture Recognizer,UIScrollView.이 목록 은 아직 많이 있 을 수 있다.
의뢰 모드 사용 방법:
ViewController.m 을 열 고 맨 위 에 다음 파일 을 가 져 옵 니 다.
#import "LibraryAPI.h"
#import "Album+TableRepresentation.h"
현재 클래스 확장 에 개인 변 수 를 추가 합 니 다.다음 과 같이 보 입 니 다.
@interface ViewController (){
UITableView *dataTable;
NSArray *allAlbums;
NSDictionary *currentAlbumData;
int currentAlbumIndex;
}
@end
현재 클래스 확장 에 있 는@interface 줄 을 바 꿉 니 다.완료 후 다음 과 같 습 니 다.
@interface ViewController () <UITableViewDataSoure, UITableViewDelegate> {
이것 이 바로 어떻게 정확 한 위탁 을 설정 하여 그것 을 하나의 위탁 으로 하나의 방법 을 이행 할 수 있 도록 허락 하 는 계약 으로 만 드 는 것 입 니까?이 는 ViewController 가 UITableView DataSource 와 UITableView Delegate 프로 토 콜 을 따 를 것 임 을 나타 낸다.이 방법 으로 UITableView 는 자신의 의뢰 방법 을 실행 해 야 합 니 다.다음은 view Did Load 를 아래 코드 로 교체 합 니 다.
- (void)viewDidLoad {
[super viewDidLoad];
// 1
self.view.backgroundColor = [UIColor colorWithRed:0.76f green:0.81f blue:0.87f alpha:1];
currentAlbumIndex = 0;
//2
allAlbums = [[LibraryAPI sharedInstance] getAlbums];
// 3
// the uitableview that presents the album data
dataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 120, self.view.frame.size.width, self.view.frame.size.height-120) style:UITableViewStyleGrouped];
dataTable.delegate = self;
dataTable.dataSource = self;
dataTable.backgroundView = nil;
[self.view addSubview:dataTable];
}
여기 서 위의 코드 를 분석 해 보 세 요.배경 색 을 예 쁜 네 이 비 로 바꾸다.
API 에서 모든 앨범 데 이 터 를 포함 하 는 목록 을 가 져 옵 니 다.Persistency Manager 를 직접 사용 할 수 없습니다.
UITableView 를 만 듭 니 다.보기 컨트롤 러 가 UITableView delegate/data source 라 고 밝 혔 습 니 다.따라서 UITableView 는 보기 컨트롤 러 에 필요 한 모든 정 보 를 제공 합 니 다.
현재 ViewController.m 에 다음 과 같은 방법 을 추가 합 니 다.
- (void)showDataForAlbumAtIndex:(int)albumIndex{
// defensive code: make sure the requested index is lower than the amount of albums
if (albumIndex < allAlbums.count) {
// fetch the album
Album *album = allAlbums[albumIndex];
// save the albums data to present it later in the tableview
currentAlbumData = [album tr_tableRepresentation];
} else {
currentAlbumData = nil;
}
// we have the data we need, let's refresh our tableview
[dataTable reloaddata];
}
showDataForAlbum AtIndex:앨범 배열 에서 필요 한 앨범 데 이 터 를 추출 합 니 다.새 데 이 터 를 표시 해 야 할 때 데 이 터 를 다시 불 러 오기 만 하면 됩 니 다(relaodData).이 는 UITableView 가 의뢰 대 리 를 요청 해 야 하기 때 문 입 니 다.몇 개의 sections 가 폼 보기에 표 시 될 것 같 습 니까?각 section 에 몇 줄 이 있 고 줄 마다 어떻게 보 입 니까?view DidLoad 에 다음 코드 추가
[self showDataForAlbumAtIndex:currentAlbumIndex];
프로그램 이 실 행 될 때 현재 앨범 정 보 를 불 러 옵 니 다.current AlbumIndex 의 미리 설 정 된 값 이 0 이기 때문에 소장 중인 첫 번 째 앨범 정 보 를 표시 합 니 다.프로젝트 를 구축 하고 실행 하면 프로그램 이 무 너 집 니 다.콘 솔 에 다음 과 같은 이상 을 입력 합 니 다.
무슨 문제 가 생 겼 습 니까?ViewController 의 UItable View 의뢰(delegate)와 데이터 원본(data source)을 밝 혔 습 니 다.그러나 이 경우 table View:numberOfRows Insection:-아직 그것 이 없습니다.
ViewController.m 의@implementation 과@end 의 어느 곳 에 나 다음 코드 를 추가 합 니 다.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [currentAlbumData[@"titles"] count];
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"];
}
cell.textLabel.text = currentAlbumData[@"titles"][indexPath.row];
cell.detailTextLabel.text = currentAlbumData[@"values"][indexPath.row];
return cell;
}
table View:numberOfRows Index Section:폼 보기에 표 시 된 줄 수 를 되 돌려 줍 니 다.데이터 구조 에 표 시 된 제목 의 수 와 일치 합 니 다.table View:cellforRow AtIndexPath:제목 과 정 보 를 가 진 cell 을 만 들 고 되 돌려 줍 니 다.
현재 프로젝트 를 구축 하고 실행 합 니 다.프로그램 이 실행 되 고 다음 그림 의 화면 을 표시 합 니 다:
이것 은 지금까지 일이 매우 좋아 보인다.하지만 첫 번 째 그림 을 돌 이 켜 보면 화면 상단 에 수평 으로 스크롤 할 수 있 는 보기 가 있어 앨범 전환 에 사용 된다.그것 은 단지 간단 한 수평 스크롤 일 뿐,왜 중복 사용 할 수 있 는 보 기 를 만 들 지 않 습 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
디자인 모델 의 공장 모델, 단일 모델자바 는 23 가지 디자인 모델 (프로 그래 밍 사상/프로 그래 밍 방식) 이 있 습 니 다. 공장 모드 하나의 공장 류 를 만들어 같은 인 터 페 이 스 를 실현 한 일부 종 류 를 인 스 턴 스 로 만 드 는 것...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.