2010-05-13 34 views
6

Gần đây tôi bắt đầu nhận thấy một sự lặp lại trong một số mã của tôi. Tất nhiên, một khi bạn nhận thấy một sự lặp lại, nó trở nên càu nhàu. Đó là lý do tại sao tôi hỏi câu hỏi này. Ý tưởng là: đôi khi bạn viết các phiên bản khác nhau của cùng một lớp: một phiên bản thô, một phiên bản bị khóa, một phiên bản mặt tiền chỉ đọc, vv Đây là những điều phổ biến để làm cho một lớp học, nhưng các bản dịch là rất cơ học. Trong một ngôn ngữ động, bạn có thể viết một hàm đã thực hiện điều này cho một thể hiện của một lớp (ví dụ: lặp qua tất cả các hàm, thay thế chúng bằng một phiên bản thu thập/giải phóng một Khóa.).Có một thuật ngữ cho khái niệm này, và nó tồn tại trong một ngôn ngữ gõ tĩnh?

Tôi nghĩ một thuật ngữ tốt cho ý tôi là 'lớp phản chiếu'. Bạn tạo một phép biến đổi lấy một lớp và trả về một lớp được sửa đổi trong một lớp mong muốn. Đồng bộ hóa là trường hợp dễ nhất, nhưng có những trường hợp khác: tạo một lớp không thay đổi [các phương thức bọc để chúng sao chép, thay đổi bản sao và gộp nó vào kết quả], tạo một lớp chỉ đọc [giả sử bạn có thể nhận biết các phương thức biến đổi], tạo một lớp xuất hiện để hoạt động với loại A thay vì loại B, v.v.

Điều quan trọng là, về mặt lý thuyết, các phép biến đổi này có ý nghĩa tại thời gian biên dịch. Mặc dù ActorModel <T> có các phương pháp thay đổi tùy thuộc vào T, chúng phụ thuộc vào T theo một cách cụ thể có thể biết được tại thời gian biên dịch (các phương thức ActorModel <T> sẽ trả về tương lai của loại kết quả ban đầu).

Tôi chỉ tự hỏi liệu điều này có được thực hiện bằng ngôn ngữ hay không và nó được gọi là gì.

Trả lời

2

Nếu tôi hiểu rõ, bạn muốn có thể tạo lớp/loại mới thông qua việc chuyển đổi loại hiện có. Một cái gì đó như

class Synchronized<T> { 
    Object invocation(Object ... args) { 
     synchronize(this) { 
      return original.invocation(args); 
     } 
    } 
} 
... 
Foo f; 
Synchronized<Foo> f2; 
f.bar(); 
f2.bar(); // would be valid for the type-system 

, nơi invocationoriginal sẽ là từ khóa cho trừu tượng cuốn tiểu thuyết này.

Kiểu mới có thể được coi là một Proxy/wrapper/bộ chuyển đổi xung quanh loại gốc. Cho dù loại mới vẫn đại diện cho một loại phụ của bản gốc hay không thì đó là một câu hỏi khác. Bao xa sự trừu tượng sẽ hỗ trợ thay đổi kiểu trả về cũng là một câu hỏi khác.

Trong khi thiết bị mã byte, AOP hoặc trình nạp lớp tùy chỉnh có thể đạt được một phần của điều này, tôi sẽ nói rằng trong tinh thần kết hợp gần nhất là một proxy động. Mã của một proxy động trông thực sự khủng khiếp tương tự như những gì tôi đã viết ở trên. Here, herehere là những tình huống tôi đã giải quyết bằng proxy động. Tất nhiên proxy động không tĩnh nhưng như tên gọi, năng động.

Tôi lo ngại rằng vấn đề chung mà bạn mô tả - cách tạo các biến thể của các loại hiện có - quá rộng. Đề xuất về loại tiện ích mở rộng hệ thống đã được thực hiện cho các tình huống cụ thể, ví dụ: cách tạo bộ điều hợp từ giao diện X sang Y sao cho tất cả việc triển khai thực hiện cụ thể X cũng có thể được xem là triển khai Y.

Có lẽ có một cái nhìn tại các giấy tờ (Tôi đã không đọc chúng tất cả, nhưng tôi có kế hoạch):

Đối với người cuối cùng, sự trừu tượng nói:

Chúng tôi thảo luận về những lợi ích chính xác và chi phí của phần mở rộng của chúng tôi về các tiêu chí giới thiệu và minh họa tính hữu ích của thống nhất sẵn proxy bằng cách triển khai phương pháp tương lai các lời gọi cả an toàn và một cách minh bạch.

, một trong những câu hỏi của bạn.

Câu hỏi hay về btw, tôi muốn giải pháp chung cho vấn đề của bạn tồn tại. Tôi không giả vờ là một chuyên gia trong chủ đề, vì vậy thậm chí có thể có một, nhưng tôi không biết.

1
+0

Nó chắc chắn có vẻ tương tự và bao gồm một số trường hợp. Nhưng, bằng cách sử dụng các khía cạnh, tôi có thể tham gia một lớp học và có phương pháp trả về tương lai thay vì các giá trị bình thường? –

+0

Thông thường bạn không thể thay đổi kiểu trả về bằng AOP, một chút của vấn đề là mã sử dụng nó không biết về các khía cạnh. –

0

Bạn không thể làm điều này với mẫu? Nó sẽ hơi bị hack, nhưng một cái gì đó như:

#define LOCKED = true; 
#define UNLOCKED = false; 

template<bool lock> 
void doStuff(){ 
    if(lock){ 
     // get lock 
    } 
    // other code 
    if(lock){ 
     // release lock 
    } 
} 
+0

Tôi không biết. Tôi chưa bao giờ thực sự khám phá các giới hạn của các mẫu C++. Họ có thể tạo một lớp có phương thức dựa trên các phương thức của lớp con không? –

+0

Bạn có thể tạo một thể hiện của lớp con của bạn dưới dạng biến thành viên và sau đó sử dụng các phương thức của nó? Hoặc nếu chúng là các hàm tĩnh, bạn có thể sử dụng chúng như 'SubclassName :: functionName()' –

0

Python có decorators liên quan đến những gì bạn đang nói đến.

+0

Tôi nghĩ rằng trang trí áp dụng cho định nghĩa, không phải là sự khởi tạo, của các lớp. Thêm vào đó, tôi đặc biệt hỏi về trường hợp tĩnh, bởi vì các ngôn ngữ động làm cho các phép biến đổi này trở nên tương đối dễ dàng. –

+0

@Strilanc: Tôi đã đọc câu hỏi của bạn nhanh hơn tôi nên làm. Nhưng trang trí chỉ là các hàm áp dụng cho các lớp, và bạn có thể trang trí một lớp nguyên tắc và khởi tạo một đối tượng cục bộ. –

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