2011-10-31 32 views
6

Ruby có gì khác với các ngôn ngữ OOP khác (ví dụ: PHP) khiến giao diện vô dụng không? Liệu nó có một số loại thay thế cho điều này?Tại sao người Ruby nói họ không cần giao diện?

Edit:

Một số làm rõ:

  • Trong các ngôn ngữ khác (ví dụ: PHP), bạn không "nhu cầu" giao diện (họ không bắt buộc ở cấp code). Bạn sử dụng chúng để thực hiện một hợp đồng, để cải thiện kiến ​​trúc của phần mềm. Do đó, sự khẳng định 'trong ruby ​​bạn không cần giao diện/bằng các ngôn ngữ khác bạn cần giao diện vì XXX' là sai.

  • Không, mixin không phải là giao diện, chúng hoàn toàn khác nhau (PHP 5.4 cài đặt mixin). Bạn đã từng sử dụng giao diện chưa?

  • Có, PHP là OOP. Ngôn ngữ phát triển, chào mừng đến hiện tại.

+5

PHP là ngôn ngữ OOP? * cười khúc khích * – NullUserException

+0

http://en.wikipedia.org/wiki/Mixin – robinjam

+0

PHP 5 (tôi nghĩ đó là phiên bản) đã giới thiệu khái niệm thiết kế OOP cho PHP nhưng nó không làm cho nó trở thành ngôn ngữ "OOP". Bạn có thể viết mã PHP kiểu OOP ngay bây giờ. –

Trả lời

0

Tôi tin rằng đó là vì Ruby được nhập động trong khi các ngôn ngữ khác được nhập tĩnh. Lý do duy nhất bạn cần sử dụng một giao diện trong PHP là khi bạn sử dụng kiểu gợi ý khi truyền các đối tượng xung quanh.

+0

Có thể là một ý tưởng hay để cụ thể hơn - ruby ​​không chỉ được gõ động, mà nó được gõ. – robinjam

+0

Trong khi chúng tôi đang tách lông, gõ vịt là một kiểu gõ động cụ thể;) –

+1

Tôi biết, đó là lý do tại sao tôi nói nó không phải là _just_ được gõ động;). Lý do nó có liên quan là bởi vì trong ruby ​​nó là một tập hợp các đối tượng và các thuộc tính hiện tại của đối tượng, không phải là siêu lớp hoặc các giao diện của nó, để xác định 'kiểu' của nó. – robinjam

0

Ruby rất năng động và được đánh máy. Điều đó có làm cho các loại giao diện vô dụng hoặc quá mức không? Giao diện lực lượng các lớp học có phương pháp nhất định có sẵn tại thời gian biên dịch.

xét này quá:

http://en.wikipedia.org/wiki/Duck_typing

+0

Giao diện hữu ích để tạo các hợp đồng giữa các lớp. – HappyDeveloper

-1

Phụ thuộc những gì bạn có ý nghĩa bởi giao diện.

Nếu theo giao diện, bạn có nghĩa là một đối tượng cụ thể tồn tại trong ngôn ngữ của bạn mà bạn kế thừa hoặc thực hiện thì không bạn không sử dụng giao diện bằng ngôn ngữ như ruby. Nếu bạn có nghĩa là giao diện như trong các đối tượng có một số giao diện tài liệu tốt thì có tất nhiên, các đối tượng vẫn có một giao diện tài liệu tốt, họ có các thuộc tính và phương pháp mà bạn mong đợi ở đó.

Tôi đồng ý rằng giao diện là thứ gì đó tồn tại trong tâm trí bạn và tài liệu chứ không phải trong mã làm đối tượng.

+0

Có Tôi biết bạn không sử dụng giao diện trong Ruby, nhưng tôi muốn biết tại sao (ngoài thực tế là tính năng này không có sẵn) – HappyDeveloper

+0

@HappyDeveloper oh, tôi đoán nó không phải là obvouis. Tại sao có chúng trong mã. Nó sưng lên. Có các giao diện trong đầu của bạn, bạn không cần một cấu trúc trong mã cho việc này. Và bên cạnh giao diện một hack bẩn cho các ngôn ngữ mà không thực hiện một hệ thống gõ thích hợp. Bạn không muốn một giao diện, bạn muốn có một loại được xác định rõ ràng trong ngôn ngữ được gõ đúng. – Raynos

+0

Tôi có thể có chúng trong đầu của tôi (trong một thời gian giới hạn) nếu tôi tạo ra các lớp học, nhưng những gì về các nhà phát triển bên cạnh tôi? Họ sẽ phải đoán. Giao diện có một vai trò rất rõ ràng, tôi không biết những gì bạn có nghĩa là bye 'họ là một hack'. Php cũng năng động, nhưng giao diện lại rất hữu ích. Ví dụ, làm thế nào bạn sẽ thực hiện các mô hình cầu? – HappyDeveloper

3

Vì ruby ​​là duck-typed, không cần giao diện riêng biệt, nhưng các đối tượng chỉ cần triển khai các phương pháp phổ biến. Hãy xem ví dụ "kinh điển" dưới đây:

class Duck 

    def move 
    "I can waddle." 
    end 

end 

class Bird 

    def move 
    "I can fly." 
    end 

end 

animals = [] 
animals << Duck.new 
animals << Bird.new 

animals.each do |animal| 
    puts animal.move 
end 

Trong ví dụ này, các "giao diện" là move phương pháp, được thực hiện bởi cả Duck và lớp Bird.

+0

Ở đây tôi chỉ có thể thấy hai lớp không có kết nối giữa chúng. Điều này khác với bất kỳ ngôn ngữ nào khác? Trong các ngôn ngữ khác bạn có thể làm tương tự, và cũng thêm một hợp đồng (thông qua giao diện), mặc dù nó không bắt buộc – HappyDeveloper

+0

@ Hài lòng, sự khác biệt là ở (hầu hết) ngôn ngữ gõ tĩnh bạn _must_ sử dụng giao diện rõ ràng để "kết nối "hai lớp. –

+0

@WayneConrad Tôi biết chúng tôi không nói về lợi thế và bất lợi của việc có thể làm điều này mà không có một giao diện rõ ràng trong chủ đề này, nhưng nó sẽ được tốt đẹp. Họ không rõ ràng với tôi. Bạn có thể xây dựng? – gabe

11

Vâng, đó là một sự đồng thuận rằng khi một đối tượng được truyền vào trong Ruby, nó không được kiểm tra kiểu. Giao diện trong Java và PHP là một cách để xác nhận rằng đối tượng tuân thủ một hợp đồng nhất định hoặc "loại" (vì vậy, có thể là Serializable, Authorizable, Sequential và bất kỳ thứ gì khác mà bạn muốn).

Tuy nhiên, trong Ruby không có khái niệm chính thức về hợp đồng mà giao diện sẽ thực hiện một số vai trò có ý nghĩa như không được kiểm tra tương thích giao diện trong phương thức. Xem, ví dụ: Enumerable. Khi bạn trộn nó vào đối tượng của bạn, bạn đang sử dụng chức năng của nó thay vì tuyên bố rằng đối tượng của bạn là Enumerable. Lợi ích duy nhất của việc có đối tượng là Enumerable là đã xác định each(&blk) bạn sẽ tự động nhận được map, select và bạn bè miễn phí. Bạn hoàn toàn có thể có một đối tượng thực hiện tất cả các phương thức được cung cấp bởi Enumerable nhưng không kết hợp trong mô-đun và nó vẫn hoạt động. Ví dụ, đối với bất kỳ phương pháp nào trong Ruby mong đợi một đối tượng IO bạn có thể nạp vào một cái gì đó có không có gì để làm với IO, và sau đó nó sẽ phát nổ với lỗi hoặc - nếu bạn đã triển khai IO của bạn một cách chính xác - nó sẽ hoạt động tốt ngay cả khi đối tượng được truyền của bạn không được khai báo là "IO-ish". Ý tưởng đằng sau đó xuất phát từ thực tế là các đối tượng trong Ruby không thực sự tôn vinh các bảng băm với một thẻ tát vào chúng (mà sau đó có một số thẻ bổ sung cho trình thông dịch hoặc trình biên dịch rằng đối tượng này có giao diện X do đó nó có thể được sử dụng trong ngữ cảnh Y) nhưng một thực thể kín trả lời các tin nhắn. Vì vậy, nếu một đối tượng đáp ứng với một thông điệp cụ thể, nó sẽ hoàn thành hợp đồng và nếu nó không phản hồi thông báo đó - thì lỗi sẽ được nâng lên.

Vì vậy, sự vắng mặt của giao diện được bù một phần bởi sự hiện diện của Mô-đun (có thể chứa chức năng mà bạn tiếp cận mà không thực hiện bất kỳ loại nào hứa hẹn cho người gọi/người tiêu dùng) và một phần bởi truyền thống truyền thông điệp. dicts.

Bạn nên xem một số bản trình bày của Jim Weirich kể từ khi chạm vào chủ đề rộng rãi.

+0

Cảm ơn, tôi sẽ xem chúng khi tôi về nhà – HappyDeveloper

3

Câu hỏi này là loại bỏ ngỏ, nhưng đây là quan điểm của tôi:

Mục đích của một tuyên bố giao diện là hai điều:

  1. Khai báo tự trong tương lai của bạn hay đồng nghiệp những gì phương pháp lớp này phải có
  2. Khai báo vào máy tính của bạn những gì phương pháp lớp này phải có

Nếu chúng ta lấy mục đích thứ hai đầu tiên, mã nguồn Ruby là không bao giờ compi dẫn đầu, do đó, không bao giờ có một tùy chọn để xác minh sự phù hợp với khai báo giao diện và cảnh báo cho nhà phát triển về bất kỳ lỗi nào không phù hợp. Điều này có nghĩa rằng nếu Ruby có một số hỗ trợ giao diện tích hợp sẵn, nó sẽ không có tùy chọn để xác minh sự phù hợp cho đến khi thời gian chạy, nơi mà ứng dụng sẽ gặp sự cố, vì việc triển khai bị thiếu.

Quay lại mục đích đầu tiên. Mã khả năng đọc. Điều này có thể có ý nghĩa và quy ước cụ thể của Ruby về việc chỉ định các giao diện có thể hữu ích. Bây giờ, bạn có lẽ sẽ giao tiếp điều này bằng cách sử dụng các nhận xét hoặc thông số kỹ thuật hoặc - như tôi có lẽ sẽ thích - một mô-đun bao gồm khai báo. Ví dụ.

module Shippable 
# This is an interface module. If your class includes this module, make sure it responds to the following methods 

    # Returns an integer fixnum representing weight in grams 
    def weight 
    raise NotImplementedError.new 
    end 

    # Returns an instance of the Dimension class. 
    def dimensions 
    raise NotImplementedError.new 
    end 

    # Returns true if the entity requires special handling. 
    def dangerous? 
    raise NotImplementedError.new 
    end 

    # Returns true if the entity is intended for human consumption and thereby must abide by food shipping regulations. 
    def edible? 
    raise NotImplementedError.new 
    end 

end 

class Product 
    include Shippable 
end 

Một cách thực thi giao diện này sẽ là bằng cách tạo ra một spec mà tạo ra một thể hiện của mỗi lớp bao gồm các module Shippable, gọi là bốn phương pháp và hy vọng họ không làm tăng NotImplementedError.

+0

Chỉ cần lưu ý, bạn không cần phải nhanh chóng khởi tạo 'NotImplementedErrors' bằng cách sử dụng' .new' - bạn chỉ có thể 'nâng cấp NotImplementedError' và nó sẽ hoạt động. – Russell

+0

Theo như tôi biết giao diện là tốt cho mục đích thử nghiệm, vì vậy trong quá trình thử nghiệm, bạn không cần phải tiêm thực hiện thực tế của tất cả các dịch vụ, nhà cung cấp, v.v. Tôi biết rằng bạn có thể tạo sơ khai trong quá trình thử nghiệm trong Ruby, nhưng bạn * phải nhớ * sau đó giả lập tất cả những thứ cần được chế nhạo. Nhưng "phải nhớ" các công cụ trong lập trình không phải là một điều tốt để viết phần mềm, đặc biệt là khi bạn làm việc trong một nhóm. – cryss

2

Tôi là một 'người Ruby' và tôi muốn có giao diện hoặc một thứ gì đó giống như họ.

Không thực thi hợp đồng - vì thực thi bất kỳ thứ gì không phải là Ruby, và đánh bại điểm của ngôn ngữ động, và dù sao cũng không có bước "biên dịch" để thực thi nó - nhưng để ghi lại hợp đồng mà lớp con của khách hàng có thể chọn để phù hợp (hoặc không, mặc dù nếu họ chọn không họ không thể khiếu nại nếu mã không hoạt động).

Khi tôi đang phải đối mặt với vấn đề này, ví dụ, khi tôi đang viết một lớp hoặc mô-đun Tôi hy vọng các lớp con để cung cấp phương pháp, tôi thường ghi lại các phương pháp tôi mong đợi các lớp con để cung cấp như thế này:

module Enumerable 
    def each 
    raise NotImplementedError, "Subclasses must provide this method" 
    end 
end 

Nó không phải là lý tưởng, nhưng đó là một trường hợp hiếm hoi hợp lý và nó hoạt động cho tôi.

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