2014-11-18 14 views
6

Tôi đang tìm các ví dụ thế giới thực (các chương trình nguồn mở) (hoặc các thuật toán) thay đổi lớp cụ thể của một đối tượng (hoặc biến) khi chạy.Thay đổi Triển khai/Lớp tại thời gian chạy

Ví dụ về hành vi như vậy trong Java có thể trông giống như trình tạo mã bên dưới. Ở đây, LinkedList, hoạt động tốt trong bối cảnh chèn và/hoặc xóa thường xuyên, được thay đổi thành một ArrayList, hoạt động tốt trong ngữ cảnh truy cập ngẫu nhiên và lặp lại.

List myList = new LinkedList(); 
/* Lots of inserts */ 
... 
myList = new ArrayList(myList); // 'change' into different class 
/* Lots of iteration */ 
... 

Ví dụ Java trên thay đổi giữa LinkedListArrayList cho vì lợi ích của hiệu suất.

Tuy nhiên, ví dụ bằng bất kỳ ngôn ngữ nào, cho bất kỳ cấu trúc dữ liệu nào, sử dụng bất kỳ kỹ thuật nào * và vì bất kỳ lý do nào đều được hoan nghênh.

* Kỹ thuật: đồng bằng và đơn giản như trong ví dụ trên, hoặc sử dụng become: trong Smalltalk, hoặc __class__ bằng Python, hoặc ...

+0

Tại chung, một câu hỏi mà yêu cầu một thư viện là tắt chủ đề ở đây. Tôi cũng không thể hiểu được mục đích đằng sau câu hỏi của bạn, vì rõ ràng là bạn hiểu lợi ích của việc làm như thế nào, và làm thế nào nó có thể được thực hiện từ ví dụ của bạn. – amit

+0

** Tôi không tìm kiếm thư viện **, tôi đang tìm "mã ví dụ", tức là, các tình huống khác trong đó các lập trình viên thay đổi cấu trúc/lớp dữ liệu của một đối tượng. Mục đích đằng sau câu hỏi của tôi là tôi cần phải xây dựng trường hợp rằng đây là một mẫu đủ phổ biến để cung cấp ngôn ngữ trừu tượng cho. – madewael

+1

Tôi thường tạo mảng động trong giai đoạn khởi tạo và sử dụng ArrayList để làm như vậy, Sau đó tôi biết rằng không có thay đổi nào nữa sẽ xảy ra tôi chuyển nó thành một mảng cũ để giảm chi phí bộ nhớ và tăng hiệu năng một chút. – MrSmith42

Trả lời

1

Không biết nếu điều này là có liên quan nhưng có lẽ việc sử dụng gián điệp (mocks một phần) cũng phù hợp với mô tả của bạn (xem http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Spy.html):

một ví dụ:

Person person = new Person(); 
person = spy(person); 
doReturn("dominiek").when(person).getName(); 

Đằng sau những cảnh một lớp con được tạo ra và hành vi của các lớp được thay đổi của tập đoàn Accor ding vào khai báo hành vi của người dùng.

2

Bạn có thể muốn kiểm tra các trường hợp sử dụng cho phương thức become trong Smalltalk. Phương thức này thay đổi lớp của cá thể tại thời gian chạy (hoặc thay đổi tất cả các tham chiếu đến cá thể để tham chiếu đến cá thể khác)

Trở thành thường được sử dụng để tăng/thu nhỏ các bộ sưu tập, ví dụ: Có thể chuyển đổi từ SmallInteger sang BigIntegers (trước đây là giới hạn về kích thước, sau này không, nhưng chậm hơn nhiều), và lập trình viên thậm chí sẽ không nhận thấy (điều này chỉ hợp lý nếu bạn có các số nguyên có thể thay đổi, thì đây không phải là cách thực hiện điều này trong Smalltalk, nhưng có thể là :)

Trường hợp khác có thể là khi tải một thể hiện từ dạng tuần tự trở lại vào hệ thống đang chạy và cập nhật lớp của nó phiên bản mới nhất.

2

Có, hãy xem #become trong Smalltalk (ví dụ như MIT được cấp phép Pharo.org).

Bên cạnh các ví dụ đã cho #become là ví dụ hữu ích khi bạn làm việc với proxy. Hãy suy nghĩ về một đối tượng proxy trong khung ORM như Glorp nơi bạn lần đầu tiên có proxy và khi cần đầy đủ đối tượng thực sự nó có thể được tải từ cơ sở dữ liệu và dễ dàng chuyển tất cả các tham chiếu.

Ví dụ khác là khung nhiên liệu ở Pharo.

1

Tôi vừa chạy qua một ví dụ về điều này trong (Python) nguồn NLTK. LazyCorpusLoader (một đối tượng được sử dụng để tải tập dữ liệu từ đĩa) "morphs" vào tập dữ liệu chính nó.Dưới đây là phần có liên quan của mã nguồn liên kết (tạo ra một đối tượng dữ liệu và sau đó trở thành nó):

corpus = self.__reader_cls(root, *self.__args, **self.__kwargs) 

    # This is where the magic happens! Transform ourselves into 
    # the corpus by modifying our own __dict__ and __class__ to 
    # match that of the corpus. 

    args, kwargs = self.__args, self.__kwargs 
    name, reader_cls = self.__name, self.__reader_cls 

    self.__dict__ = corpus.__dict__ 
    self.__class__ = corpus.__class__ 

Dưới đây là lý do căn bản nhất định (trong phần đầu của cùng một tập tin) cho kỹ thuật này:

LazyCorpusLoader là một đối tượng proxy được sử dụng để đứng trong một đối tượng corpus trước khi kho được nạp. Điều này cho phép NLTK tạo đối tượng cho mỗi kho văn bản, nhưng trì hoãn các chi phí liên quan khi tải những tập đoàn đó cho đến lần đầu tiên chúng thực sự được truy cập .

Vì vậy, mục đích thay đổi lớp lúc chạy trong trường hợp này là để mô phỏng đánh giá lười biếng.

(Edit: Vì tôi là trích dẫn nguyên văn từ nguồn NLTK (Apache 2.0), đây là liên kết bắt buộc với giấy phép bản thân: http://www.apache.org/licenses/LICENSE-2.0)

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