Apa sebenarnya yang disebut "Cluster Kelas" di Objective-C?

91

Saya membaca bahwa NSArray memang seperti itu. Kedengarannya berat. Saya memiliki 7 buku yang sangat gemuk di meja saya tentang Objective-C, Cocoa, dan C. Tidak ada satupun dari mereka yang menyebutkan Class Cluster sama sekali, setidaknya saya tidak dapat menemukannya di Index di bagian belakang buku. Jadi apa itu?

katak terbuka
sumber
Ups, lain kali saya akan berpikir untuk menambahkan tautan untuk istilah itu. Jika Anda akan mengomentari jawaban atas pertanyaan Anda sebelumnya, saya akan menjawabnya di sana.
Georg Fritzsche
2
FWIW: baru-baru ini (Des 2013) Apple merekomendasikan penggunaan Class Clusters sebagai cara untuk menangani kompatibilitas mundur ke iOS 6 saat menggunakan iOS 7. Ini ada di Apple Tech Talks 2013 / Berlin dalam sesi "Merancang Aplikasi Modern, Bagian 2". Apple mengatakan bahwa mereka akan memposting video sesi tak lama setelah acara terakhir (17. Des). Jadi mungkin ini akan membantu untuk memahami Klaster Kelas dalam konteks sebenarnya dari perubahan iOS 6/7.
Brainray

Jawaban:

42

Dari docs Apple ... . Singkatnya, ini adalah pola desain yang digunakan dalam kerangka Foundation, yang mungkin mengapa tidak disebutkan dalam buku ObjC.

Cluster kelas adalah arsitektur yang mengelompokkan sejumlah subkelas konkret dan privat di bawah kelas super abstrak publik. Pengelompokan kelas dengan cara ini menyediakan antarmuka yang disederhanakan bagi pengguna, yang hanya melihat arsitektur yang terlihat secara publik.

gema
sumber
1
roflmao.dll Terima kasih. akan google lain kali. berpikir jika itu tidak ada di buku gemuk saya, itu hanya bisa ada di kepala Anda;)
openfrog
1
Satu hal yang hilang dari tautan ini adalah penjelasan tentang cara terbaik mengubah implementasi untuk ARC.
Hiperbola
193

Saya tidak tahu apa yang ada di CDP yang dirujuk Steve tetapi pada dasarnya Cluster Kelas Objective-C adalah konstruksi yang mendukung penerapan pola Pabrik abstrak .

The Ide sederhana : Anda ingin memberikan Factory (Cluster) antarmuka yang, dengan deskripsi minimal, memproduksi dan kembali contoh konkret tertentu dari sebuah Object Pabrik yang memenuhi perilaku keluarga klaster dijelaskan oleh Factory (Cluster) interface.

Contoh konkret sederhana : Contoh ini memberikan pabrik Tertawa yang memproduksi kelas konkret dari jenis tertawa tertentu (misalnya, Guffaw, Giggle). Perhatikan Tertawa initWithLaughter: metode.

Dalam Laugh.h:

#define kLaughWithGuffaw  1
#define kLaughWithGiggle  2

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

Dalam 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
Frank C.
sumber
24
Sementara jawaban lain bagus menyediakan tautan dokumen & buku, saya suka ini karena membuatnya bagus dan sederhana untuk melihat bagaimana sebenarnya melakukan ini. Terima kasih
jamone
Contoh ini bagus tetapi dalam pola Pabrik yang khas, subkelasnya bersifat publik. Dalam cluster Kelas, subclass bersifat pribadi. developer.apple.com/library/ios/documentation/general/…
maxpower
1
@ AdriàNavarro Mereka tidak terlihat dari luar karena mereka dideklarasikan di .m-file.
hfossli
4
(1) Seberapa amankah melepaskan diri dalam suatu initmetode, dan mengembalikan sesuatu yang lain? Apakah ada contoh kode dari Apple di mana mereka melakukan ini? (2) Selain itu, Anda mungkin membuat instance dengan kode seperti [[Laugh alloc] initWithLaughter:kLaughWithGiggle]. Perhatikan bagaimana Laughdialokasikan secara tidak perlu, karena itu akan dirilis segera setelah panggilan ini. Mengapa melakukannya dengan cara ini ketika Anda dapat membuat metode kelas seperti [Laugh laughWithLaughter:kLaughWithGiggle]yang memberi Anda semua keuntungan dari subkelas privat, sambil menghindari masalah 1 & 2 di atas?
Senseful
1
@ Senseful Anda benar. Dalam kehidupan nyata, +allocmengembalikan kelas pabrik tunggal yang mengimplementasikan berbagai -initWith:metode. Metode kelas pabrik -initWith:kemudian bertanggung jawab untuk mengalokasikan dan menginisialisasi subkelas konkret berdasarkan parameter metode yang diberikan, jika perlu, atau dalam beberapa kasus mungkin tidak mengalokasikan apa pun (seperti -[NSString initWithString:]). Anda dapat mencobanya dengan melakukan pemeriksaan pada nilai kembali dari +[NSString alloc], +[NSArray alloc], dll
Darren
25

Dari pemrograman dalam tujuan c oleh Stephen Kochan di halaman 498 dalam glosarium, cluster:

Kelas abstrak yang mengelompokkan sekumpulan subkelas beton pribadi, menyediakan antarmuka yang disederhanakan kepada pengguna melalui kelas abstrak.

t011phr33
sumber
5
+1 Untuk mengutip jawaban dari buku Objective-C, khususnya untuk pertanyaan aslinya. Itu buku yang bagus juga.
Quinn Taylor
(+1) untuk definisi yang sangat baik. Masalah yang saya hadapi dengan menyebut ini pola "Pabrik" adalah bahwa nama seperti itu hanya berfokus pada pembuatan objek, bukan interaksi under-the-hood dari subclass privat seperti yang dikelola oleh superclass abstrak. Memang, bahkan menyebut superclass ini "abstrak" bisa menyesatkan karena sebenarnya sangat (secara internal) bergantung pada subkelasnya sendiri, dan oleh karena itu bukan kelas abstrak normal yang umumnya tidak tahu apa-apa tentang subkelasnya.
devios1
18

Kluster kelas menyediakan antarmuka publik tunggal ke sekelompok implementasi subkelas pribadi yang konkret. Seorang programmer objektif-c sering menggunakan cluster kelas dan jarang menyadarinya - dan inilah inti dari cluster kelas. Tugas cluster kelas adalah menyembunyikan kompleksitas detail implementasi di balik antarmuka publik.

Banyak dari kelas Foundation adalah cluster kelas, seperti NSString, NSArray, NSDictionary, dan NSNumber. Ketika Anda memanggil [NSString stringWithFormat:]cluster kelas memberi Anda beberapa kelas konkret yang mengimplementasikan NSStringantarmuka. Ini bisa menjadi NSConcreteString, NSCFString, NSFooBarString, dll yang cluster kelas memberi Anda didasarkan pada konstruktor atau initializer Anda panggil dan argumen.

Karena itu, cluster kelas adalah salah satu konsep yang paling memberdayakan dalam pemrograman Objective-C.

  • Sangat mudah diimplementasikan
  • Mudah untuk mengubah implementasi yang mendasarinya tanpa mengubah kode yang memanggilnya.
  • Mudah untuk menyediakan implementasi konkret yang berbeda pada waktu proses (yaitu sumber daya pengujian atau objek tiruan)
  • Karena hal di atas, mudah untuk diuji dan difaktor ulang

Jika Anda berasal dari bahasa lain, Anda mungkin akrab dengan pola Gang of Four. Cluster kelas memiliki elemen pabrik abstrak dan pola fasad.

Dokumentasi publik Apple mencakup cluster kelas (dan cara menerapkan serta memperluasnya) secara ekstensif. Sayangnya, saya telah menemukan bahwa bagi banyak pengembang iOS ini dan pola khusus Kakao lainnya adalah titik buta.

Kompetensi Inti Kakao: Gugus kelas

Panduan Dasar-dasar Kakao: Kelompok Kelas

Contoh cara mengimplementasikan cluster kelas Anda sendiri tersedia di GitHub

memadamkan
sumber
7

Gugus kelas NSArray bukanlah "kelas berat", ini adalah cara agar sejumlah implementasi kelas array digunakan tanpa kode Anda mengetahui atau peduli tentang implementasi tertentu. Di bawah tenda, ada subclass konkret NSArray yang sesuai untuk kasus penggunaan yang berbeda, seperti array yang besar, jarang, atau array yang berisi sejumlah elemen tertentu yang diketahui pada waktu kompilasi.

NSArray, NSString, dan NSNumber adalah cluster kelas yang paling sering Anda temui.

NSResponder
sumber
6
Ironisnya, dalam praktiknya, hanya satu kelas konkret per cluster yang pernah digunakan lagi - NSCF {Array | String | Number} - dan perubahan implementasi bersifat internal ke kelas tersebut. Itu sejauh yang saya tahu. Bahkan instance NSArray dan NSMutableArray menampilkan kelas yang sama.
Chuck
1
@ Chuck - bagaimana ini bisa terjadi? Jika NSMutableArray dan NSArray melaporkan diri mereka sendiri sebagai kelas yang sama tidak akan [myArray isKindOfClass:[NSMutableArray class]]mengembalikan YA meskipun seharusnya tidak?
Robert
1
@Robert: Dan memang itulah yang terjadi pada saat saya memberikan komentar. Saat ini Apple telah mengganti NSCFArray dengan __NSArrayM dan __NSArrayI, jadi menurut saya tidak lagi demikian, tetapi saya masih tidak akan merasa nyaman bergantung padanya, karena mereka selalu dapat mengubahnya lagi.
Chuck