2012-05-10 25 views
9

Giả sử tôi đang tạo một lớp Objective-C đại diện cho một phần nhỏ và muốn tạo các phiên bản không thể thay đổi và có thể thay đổi được.Cách hiệu quả nhất để tạo ra các phiên bản bất biến và có thể thay đổi của một lớp khách quan-c là gì?

Theo các mẫu trong khuôn khổ Nền tảng, bạn có thể thấy phương thức fractionByAddingFraction: trong phiên bản bất biến và addFraction: trong phiên bản có thể thay đổi.

Nghịch lý mà tôi đang gặp phải là cách chỉ bao gồm logic thêm phân số một lần giữa hai lớp. Dường như phương pháp fractionByAddingFraction: bất biến cần biết (và sử dụng) phương pháp addFraction: có thể thay đổi để tránh trùng lặp mã, và bao gồm các phương pháp có thể thay đổi trong việc thực hiện lớp không thay đổi có nghĩa là chúng có thể được gọi là không thay đổi đối tượng, đánh bại điểm.

Giải thích ngắn gọn (hoặc tốt hơn nữa, việc tiếp tục ví dụ đơn giản này) sẽ được nhiều người đánh giá cao!

+4

Ví dụ lớp học của bạn dường như đại diện cho một đối tượng _value_, vì vậy tôi không nghĩ bạn nên cung cấp một phiên bản có thể thay đổi cho nó. __Chỉ cần biến nó thành không thay đổi .__ –

+0

@ Jordão Với ví dụ cụ thể này, bạn hoàn toàn đúng. Tôi chỉ cảm thấy rằng đây là cách dễ nhất và ngắn gọn nhất để giải thích sự nhầm lẫn của tôi về khái niệm nói chung (vì nó liên quan đến các lớp phức tạp hơn). Bất kỳ suy nghĩ về cách nó sẽ được thực hiện bất kể? – user1385983

Trả lời

3

Cách tiếp cận của bạn là chính xác (nếu bạn thực sự cần một lớp con có thể thay đổi, bạn nên tránh trừ khi bạn thực sự cần nó). Tôi không hoàn toàn rõ ràng nơi mà sự nhầm lẫn đang đến. Bạn sẽ dễ dàng thực hiện addFraction: nhất bằng cách sử dụng fractionByAddingFraction:. Nó sẽ là một chút không hiệu quả, nhưng đó là hướng mà sẽ làm cho ý nghĩa nhất. Một cái gì đó như:

- (void)addFraction:(Fraction *)anotherFraction { 
    Fraction *newFraction = [self fractionByAddingFraction:anotherFraction]; 
    self.internalStuff = newFraction.internalStuff; 
} 

Nhưng thông thường bạn có thể xử lý điều này hiệu quả hơn với một số chức năng riêng tư mà cả hai lớp sẽ sử dụng.

+0

Cảm ơn các đề xuất. Tôi đã tránh được cách tiếp cận đầu tiên đơn giản bởi vì, như bạn đã đề cập, nó có thể không hiệu quả để tạo ra một đối tượng mới mỗi lần bất kỳ thành phần nào của nó được thay đổi. Ý tưởng của bạn về việc tạo một hàm riêng dường như là một lựa chọn tốt, tuy nhiên, tôi tự hỏi vị trí lý tưởng sẽ được đặt ở đâu để có thể truy cập vào cả hai lớp, nhưng không thể truy cập được vào bất kỳ thứ gì khác (quy tắc đưa nó vào tiêu đề)? – user1385983

+0

Điều này thường được thực hiện với tiêu đề riêng tư như Phân số + Riêng tư.h. Lưu ý rằng bạn có thể vẫn muốn xem xét bỏ qua biểu mẫu có thể thay đổi nếu đó là loại điều này. Lưu ý cách NSNumber không có dạng có thể thay đổi. Trừ khi bạn đang tạo ra nhiều người trong số họ rất nhanh, sự đơn giản và an toàn thread của các đối tượng giá trị làm cho chúng rất hấp dẫn. Ngay cả khi bạn thực hiện chúng rất nhanh chóng, bạn có thể cache một số trong số chúng. NSNumber lưu trữ các số nguyên -1-12 làm đơn như tôi nhớ lại. Bạn có thể thực hiện loại bộ nhớ đệm đó dễ dàng nhất với các đối tượng bất biến. Nhưng ở trên là cách bạn xử lý nó khi bạn cần sự biến đổi. –

+0

Hãy nhớ rằng bạn có thể đi và xem các đối tượng CoreFoundation cơ bản được triển khai như thế nào: http://opensource.apple.com/source/CF/CF-635/CFArray.c. –

0

Các triển khai chính của bộ sưu tập của Quỹ lừa gạt: chỉ có một triển khai, là một lớp con của NSMutableFoo và có cờ có thể thay đổi riêng tư. Điều này có nghĩa là mã khách hàng không thể kiểm tra xem một đối tượng cụ thể có thể thay đổi hay không, nhưng điều đó sẽ không bao giờ là một ý tưởng hay, ngoại trừ có lẽ để gỡ lỗi và xác nhận.

+0

Tôi hiểu chính xác rằng 'NSFoo' sẽ là phân lớp của 'NSMutableFoo' và 'NSMutableFoo' sẽ chứa tất cả các phương thức cho cả hai lớp, tuy nhiên, giới hạn khả năng của lớp con không thể thay đổi được dựa trên cờ riêng? – user1385983

+0

'NSFoo' không phải là phân lớp của' NSMutableFoo', không. Mối quan hệ thường là 'NSFoo' ←' NSMutableFoo' ← 'NSCFFoo', trong đó' NSCFFoo' là một sự thực thi cụ thể. Các phương pháp đột biến của 'NSCFFoo' kiểm tra cờ có thể thay đổi và ném một ngoại lệ nếu nó không thay đổi được. (Thực tế thực sự phức tạp hơn điều này vì cầu nối miễn phí, nhưng đó là cách nó sẽ hoạt động mà không cần CF tham gia.) Đối với các lớp học của riêng bạn, bạn có thể gọi lớp con cụ thể như 'XYConcreteFoo'. –

Các vấn đề liên quan