สิ่งที่เรียกว่า“ Class Cluster” ใน Objective-C คืออะไร?


91

ฉันกำลังอ่านว่า NSArray เป็นเพียงสิ่งนั้น ฟังดูหนักหนา ฉันมีหนังสืออ้วนจริงๆ 7 เล่มบนโต๊ะทำงานเกี่ยวกับ Objective-C, Cocoa และ C ไม่มีใครพูดถึง Class Cluster เลยอย่างน้อยก็หาไม่เจอใน Index ที่ด้านหลังของหนังสือ แล้วนั่นคืออะไร?


อ๊ะครั้งหน้าฉันคิดจะเพิ่มลิงค์สำหรับคำนั้น หากคุณจะแสดงความคิดเห็นเกี่ยวกับคำตอบของคำถามก่อนหน้านี้ฉันได้ตอบไปที่นั่น
Georg Fritzsche

2
FWIW: เมื่อเร็ว ๆ นี้ (ธันวาคม 2013) Apple แนะนำให้ใช้ Class Clusters เป็นวิธีจัดการความเข้ากันได้แบบย้อนหลังกับ iOS 6 ในขณะที่ใช้ iOS 7 นี่คือใน Apple Tech Talks 2013 / Berlin ในเซสชั่น "Architecting Modern Apps ตอนที่ 2" Apple กล่าวว่าพวกเขาจะโพสต์วิดีโอของการประชุมในไม่ช้าหลังจากเหตุการณ์สุดท้าย (17 ธ.ค. ) ดังนั้นอาจจะช่วยให้เข้าใจ Class Clusters ภายในบริบทจริงของการเปลี่ยนแปลง iOS 6/7
brainray

คำตอบ:


42

จากเอกสารของแอปเปิ้ล ... ในระยะสั้นเป็นรูปแบบการออกแบบที่ใช้ในกรอบของมูลนิธิซึ่งอาจเป็นเหตุผลว่าทำไมจึงไม่กล่าวถึงในหนังสือ ObjC

คลัสเตอร์คลาสคือสถาปัตยกรรมที่จัดกลุ่มคลาสย่อยที่เป็นส่วนตัวและเป็นรูปธรรมภายใต้คลาสซูเปอร์คลาสนามธรรมสาธารณะ การจัดกลุ่มคลาสด้วยวิธีนี้ทำให้อินเทอร์เฟซที่เรียบง่ายสำหรับผู้ใช้ซึ่งมองเห็นเฉพาะสถาปัตยกรรมที่เปิดเผยต่อสาธารณะ


1
Roflmao. ขอบคุณ. คราวหน้าจะใช้ Google คิดว่าถ้ามันไม่ได้อยู่ในหนังสืออ้วนของฉันมันจะอยู่บนหัวของคุณเท่านั้น)
openfrog

1
สิ่งหนึ่งที่ขาดหายไปของลิงก์นี้คือคำอธิบายเกี่ยวกับวิธีปรับเปลี่ยนการใช้งาน ARC
Hyperbole

193

ฉันไม่รู้ว่ามีอะไรอยู่ใน CDP ที่ Steve อ้างถึง แต่โดยพื้นฐานแล้ว Objective-C Class Cluster เป็นโครงสร้างที่สนับสนุนการใช้รูปแบบโรงงานนามธรรม

ความคิดเป็นเรื่องง่าย : คุณต้องการที่จะให้โรงงาน (คลัสเตอร์) อินเตอร์เฟซที่มีคำอธิบายน้อยที่สุดผู้ผลิตและผลตอบแทนเช่นคอนกรีตที่เฉพาะเจาะจงของวัตถุโรงงานที่ตอบสนองพฤติกรรมของครอบครัวคลัสเตอร์อธิบายโดยอินเตอร์เฟซที่โรงงาน (คลัสเตอร์)

ตัวอย่างที่เป็นรูปธรรมง่ายๆ : ตัวอย่างนี้เป็นโรงงาน Laugh ที่สร้างคลาสของเสียงหัวเราะเฉพาะประเภท (เช่น Guffaw, Giggle) ให้ความสนใจกับLaugh initWithLaughter: method

ใน Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

@interface Laugh: NSObject {}
- (Laugh *) initWithLaughter:(NSUInteger) laughterType;
- (void) laugh;
@end

ใน Laugh.m:

@interface Guffaws:Laugh {}
- (void) laugh;
@end

@interface Giggles:Laugh {}
- (void) laugh;
@end

@implementation Laugh
- (Laugh *) initWithLaughter:(NSUInteger) laugherType {
    id instanceReturn=nil;
    ; // Removed for ARC [self release]
    if ( laughterType == kLaughWithGuffaw )
        instanceReturn = [[Guffaws alloc]init];
    else if( laughterType == kLaughWithGiggle )
        instanceReturn = [[Giggles alloc]init];
    else
        ; // deal with this
    return instanceReturn;
}

- (void) laugh {
    NSLog(@"Humbug");
}
@end

@implementation Guffaws
    - (void) laugh {
        NSLog(@"OH HA HA HOWAH HA HA HA");
    }
@end

@implementation Giggles
    - (void) laugh {
        NSLog(@"Tee hee");
    }
@end

24
ในขณะที่คำตอบอื่น ๆ นั้นดีในการให้ลิงก์ doc & book แต่ฉันชอบสิ่งนี้เพราะมันทำให้ดีและง่ายในการดูวิธีการทำเช่นนี้ ขอบคุณ
jamone

ตัวอย่างนี้ดี แต่ในรูปแบบโรงงานทั่วไปคลาสย่อยเป็นแบบสาธารณะ ในคลัสเตอร์คลาสคลาสย่อยเป็นแบบส่วนตัว developer.apple.com/library/ios/documentation/general/…
maxpower

1
@ AdriàNavarroพวกเขาไม่สามารถมองเห็นได้จากภายนอกเนื่องจากมีการประกาศในไฟล์.m-file.
hfossli

4
(1)การปลดปล่อยตัวเองด้วยinitวิธีใดปลอดภัยเพียงใดและส่งคืนอย่างอื่น มีตัวอย่างโค้ดจาก Apple ที่ใช้ทำสิ่งนี้หรือไม่? (2)นอกจากนี้คุณน่าจะสร้างอินสแตนซ์ด้วยรหัสเช่น[[Laugh alloc] initWithLaughter:kLaughWithGiggle]. สังเกตว่าLaughมีการจัดสรรโดยไม่จำเป็นอย่างไรเนื่องจากจะถูกปล่อยทันทีหลังจากการโทรนี้ เหตุใดจึงเป็นเช่นนี้เมื่อคุณสามารถสร้างเมธอดคลาสเช่น[Laugh laughWithLaughter:kLaughWithGiggle]ซึ่งให้ข้อดีทั้งหมดของคลาสย่อยส่วนตัวในขณะที่หลีกเลี่ยงปัญหา 1 & 2 ข้างต้น
Senseful

1
@Senseful คุณพูดถูก ในชีวิตจริง+allocส่งคืนคลาสโรงงานเดี่ยวที่ใช้-initWith:วิธีการต่างๆ -initWith:จากนั้นวิธีการของคลาสโรงงานจะรับผิดชอบในการจัดสรรและกำหนดค่าเริ่มต้นคลาสย่อยที่เป็นรูปธรรมตามพารามิเตอร์วิธีการที่กำหนดหากจำเป็นหรือในบางกรณีอาจไม่จัดสรรอะไรเลย (เช่น-[NSString initWithString:]) คุณสามารถทดลองใช้งานได้โดยการตรวจสอบที่ค่าตอบแทนของ+[NSString alloc], +[NSArray alloc]ฯลฯ
คาร์เรน

25

จากการเขียนโปรแกรมในวัตถุประสงค์ c โดย Stephen Kochan ที่หน้า 498 ในอภิธานศัพท์คลัสเตอร์:

คลาสนามธรรมที่จัดกลุ่มชุดของคลาสย่อยคอนกรีตส่วนตัวจัดเตรียมอินเทอร์เฟซที่เรียบง่ายให้กับผู้ใช้ผ่านคลาสนามธรรม


5
+1 สำหรับการอ้างคำตอบจากหนังสือ Objective-C โดยเฉพาะคำถามเดิม นั่นเป็นหนังสือที่ดีเช่นกัน
Quinn Taylor

(+1) สำหรับคำจำกัดความที่ยอดเยี่ยม ปัญหาที่ฉันมีในการเรียกรูปแบบนี้ว่า "โรงงาน" คือชื่อดังกล่าวมุ่งเน้นไปที่การสร้างวัตถุเท่านั้นไม่ใช่การโต้ตอบภายใต้ฝากระโปรงของคลาสย่อยส่วนตัวที่จัดการโดยคลาสซูเปอร์คลาสนามธรรม อันที่จริงแม้แต่การเรียกซูเปอร์คลาสนี้ว่า "นามธรรม" ก็อาจทำให้เข้าใจผิดได้เนื่องจากในความเป็นจริงแล้วค่อนข้าง (ภายใน) ขึ้นอยู่กับคลาสย่อยของตัวเองดังนั้นจึงไม่ใช่คลาสนามธรรมธรรมดาซึ่งโดยทั่วไปไม่รู้อะไรเกี่ยวกับคลาสย่อยของมัน
devios1

18

คลัสเตอร์คลาสจัดเตรียมอินเทอร์เฟซสาธารณะเดียวให้กับกลุ่มของการใช้งานคลาสย่อยส่วนตัวที่เป็นรูปธรรม โปรแกรมเมอร์วัตถุประสงค์ -c ใช้คลัสเตอร์คลาสบ่อยครั้งและแทบไม่ได้ตระหนักถึงมัน - และนี่คือจุดรวมของคลัสเตอร์คลาส หน้าที่ของคลาสคลัสเตอร์คือการซ่อนความซับซ้อนของรายละเอียดการใช้งานไว้เบื้องหลังอินเทอร์เฟซสาธารณะ

คลาส Foundation จำนวนมากเป็นกลุ่มคลาสเช่น NSString, NSArray, NSDictionary และ NSNumber เมื่อคุณเรียก[NSString stringWithFormat:]คลาสคลัสเตอร์จะทำให้คุณมีคลาสคอนกรีตที่ใช้NSStringอินเทอร์เฟซ มันอาจจะเป็นNSConcreteString, NSCFString, NSFooBarStringฯลฯ ซึ่งคลัสเตอร์ชั้นเรียนจะช่วยให้คุณขึ้นอยู่กับการสร้างหรือการเริ่มต้นคุณโทรและข้อโต้แย้ง

ด้วยเหตุนี้คลัสเตอร์คลาสจึงเป็นหนึ่งในแนวคิดที่ช่วยเพิ่มขีดความสามารถในการเขียนโปรแกรม Objective-C

  • ใช้งานง่ายมาก
  • ง่ายต่อการเปลี่ยนการใช้งานพื้นฐานโดยไม่ต้องเปลี่ยนรหัสที่เรียกมัน
  • ง่ายต่อการจัดเตรียมการใช้งานคอนกรีตที่แตกต่างกันในรันไทม์ (เช่นทรัพยากรทดสอบหรือวัตถุจำลอง)
  • ด้วยเหตุดังกล่าวข้างต้นจึงง่ายต่อการทดสอบและ refactor

หากคุณมาจากภาษาอื่นคุณอาจคุ้นเคยกับรูปแบบ Gang of Four กลุ่มคลาสมีองค์ประกอบของทั้งโรงงานนามธรรมและรูปแบบซุ้ม

เอกสารสาธารณะของ Apple ครอบคลุมคลัสเตอร์คลาส (และวิธีการใช้งานและขยาย) ค่อนข้างครอบคลุม น่าเสียดายที่ฉันพบว่าสำหรับนักพัฒนา iOS หลายคนสิ่งนี้และรูปแบบเฉพาะของ Cocoa อื่น ๆ เป็นจุดบอด

สมรรถนะหลักของโกโก้: กลุ่มคลาส

คู่มือความรู้พื้นฐานเกี่ยวกับโกโก้: กลุ่มคลาส

ตัวอย่างวิธีใช้คลัสเตอร์คลาสของคุณเองมีอยู่ใน GitHub


7

คลัสเตอร์คลาส NSArray ไม่ใช่ "เฮฟวี่เวท" แต่เป็นวิธีสำหรับการใช้งานคลาสอาร์เรย์จำนวนเท่าใดก็ได้โดยที่โค้ดของคุณไม่ทราบหรือสนใจเกี่ยวกับการนำไปใช้งานนั้น ๆ ใต้ฝากระโปรงมีคลาสย่อยที่เป็นรูปธรรมของ NSArray ที่เหมาะสมกับกรณีการใช้งานที่แตกต่างกันเช่นอาร์เรย์ขนาดใหญ่ที่กระจัดกระจายหรืออาร์เรย์ที่มีองค์ประกอบเฉพาะจำนวนหนึ่งซึ่งเป็นที่ทราบกันดีในเวลาคอมไพล์

NSArray, NSString และ NSNumber เป็นกลุ่มคลาสที่คุณจะพบบ่อยที่สุด


6
น่าแปลกที่ในทางปฏิบัติมีการใช้คลาสคอนกรีตเพียงคลาสเดียวต่อคลัสเตอร์อีกต่อไป - NSCF {Array | String | Number} - และการเปลี่ยนแปลงการนำไปใช้งานจะอยู่ภายในคลาสนั้น เท่าที่ฉันรู้อย่างไรก็ตาม แม้แต่อินสแตนซ์ NSArray และ NSMutableArray ก็แสดงคลาสเดียวกัน
Chuck

1
@ ชัค - เป็นแบบนี้ได้ยังไง? หาก NSMutableArray และ NSArray รายงานว่าตัวเองเป็นคลาสเดียวกันจะไม่[myArray isKindOfClass:[NSMutableArray class]]ส่งคืน YES แม้ว่าจะไม่ควร?
Robert

1
@ โรเบิร์ต: และนั่นก็เป็นเช่นนั้นในเวลาที่ฉันแสดงความคิดเห็น ปัจจุบัน Apple ได้แทนที่ NSCFArray ด้วย __NSArrayM และ __NSArrayI ดังนั้นฉันคิดว่ามันไม่เป็นเช่นนั้นอีกต่อไป แต่ฉันก็ยังไม่สบายใจขึ้นอยู่กับมันเพราะพวกเขาสามารถเปลี่ยนได้อีกครั้ง
Chuck
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.