Kế thừa vs mixin trong ngôn ngữ động?


19

Khi nào bạn nên thích các mẫu thừa kế hơn mixin trong các ngôn ngữ động?

Theo mixins, tôi có nghĩa là thực sự trộn đúng, như khi chèn các hàm và thành viên dữ liệu vào một đối tượng trong thời gian chạy.

Khi nào bạn sẽ sử dụng, ví dụ, thừa kế nguyên mẫu thay vì mixins? Để minh họa rõ hơn những gì tôi muốn nói về mixin, một số mã giả:

asCircle(obj) {
  obj.radius = 0
  obj.area = function() {
    return this.radius * this.radius * 3.14
  }

myObject = {}
asCircle(myObject)
myObject.area() // -> 0

2
Mixins giống như các khía cạnh xuyên suốt hơn là kế thừa thẳng. Điều đó có thể sẽ xác định một số trường hợp sử dụng cho bạn.
tro999

1
Thành phần, bất cứ ai :)
OnesimusUnbound

Câu trả lời:


14

Kế thừa nguyên mẫu là đơn giản. Nó có một lợi thế duy nhất so với mixins.

Đó là một liên kết trực tiếp. nếu bạn thay đổi nguyên mẫu, mọi thứ kế thừa nó sẽ được thay đổi.

Ví dụ sử dụng pd

var Circle = {
  constructor: function _constructor() {
    this.radius = 0;
    return this;
  },
  area: function _area() {
    return this.radius * this.radius * Circle.PI
  },
  PI: 3.14
};

var mixedIn = pd.extend({}, Circle).constructor();
var inherited = pd.make(Circle, {}).constructor();

Circle.perimeter = perimeter;

inherited.perimeter(); // wins
mixedIn.perimeter(); // fails

function perimeter() {
  return 2 * this.radius;
}

Về cơ bản, nếu bạn muốn các thay đổi đối với Vòng tròn "giao diện" phản ánh trong thời gian chạy tới tất cả các đối tượng "sử dụng" chức năng của nó, thì hãy kế thừa từ nó.

Nếu bạn không muốn thay đổi để phản ánh thì hãy trộn nó vào.

Lưu ý rằng mixins có nhiều mục đích hơn là tốt. Mixins là cơ chế của bạn cho nhiều "sự kế thừa".

Nếu bạn muốn một đối tượng triển khai nhiều "giao diện" thì bạn sẽ phải kết hợp một số. Cái mà bạn sử dụng để thừa kế nguyên mẫu là thứ bạn muốn thay đổi để phản ánh trong thời gian chạy, những cái khác sẽ được trộn lẫn vào.


12

Cảm giác ngựa của tôi nói với tôi điều này:

  • Nếu một cái gì đó hữu ích trên nhiều đối tượng hoặc phân cấp lớp - hãy biến nó thành một hỗn hợp
  • Nếu có điều gì đó chỉ hữu ích cùng một hệ thống duy nhất - sử dụng thừa kế

Ghi chú liên quan:

  • Từ "hữu ích" nên được dùng theo nghĩa bóng
  • Đối với những ngôn ngữ không có nhiều kế thừa, mixin là một lựa chọn tốt
  • PHP 5.4 giới thiệu các đặc điểm có tính tốt từ cả hai mixin và nhiều thế giới thừa kế

+1, ví dụ yêu thích của tôi về "thứ gì đó hữu ích trên nhiều đối tượng hoặc phân cấp lớp" trong Ruby là mô-đun có thể đếm được: ruby-doc.org/core-1.9.3/Enumerable.html
David

1
Tôi muốn nói rằng nhiều kế thừa có thể là một sự thay thế (không tốt lắm) cho mixins.
Simon Bergot

@Simon Tôi sẽ nói rằng mixins có thể là một sự thay thế (không tốt lắm) cho nhiều kế thừa;)
Raynos

Cảm giác ngựa của tôi cũng nói với tôi điều này. :)
theringostarrs

9

Sử dụng bài kiểm tra "Is-a".

Kế thừa được giới hạn trong trường hợp khi bạn có thể nói "Lớp con là siêu lớp". Họ là cùng một loại điều. "Phô mai là một sản phẩm sữa".

Mixins là dành cho mọi thứ khác. "Pho mát có thể được sử dụng trong một bánh sandwich". Phô mai không phải là bánh sandwich, nhưng nó tham gia vào bánh sandwich.

Tái bút Điều này không có gì để làm với các ngôn ngữ động. Bất kỳ ngôn ngữ thừa kế nào có biên dịch tĩnh (nghĩa là C ++) đều có cùng một điểm quyết định.


Chắc chắn + 1- ngôn ngữ tĩnh cũng có mixins.
DeadMG

Đúng, mixins có thể được thực hiện bằng nhiều ngôn ngữ - đây không phải là câu hỏi của tôi. Các ngôn ngữ động có các thuộc tính nhất định có thể hoặc không thể tạo ra các mixin khác nhau và / hoặc thú vị hơn trong các ngôn ngữ đó - Raynos đã chỉ ra một khía cạnh. Hơn nữa, bạn không chỉ ra bất kỳ lý do cụ thể nào tại sao người ta nên sử dụng khái niệm IS A trên khái niệm mixin.
Magnus Wolffelt

@MagnusWolffelt: Chúng là cùng một loại. "Phô mai là một sản phẩm sữa". Đó là quy tắc cho IS-A. Tôi nên nói gì thêm nữa?
S.Lott

Câu hỏi của tôi là nhiều hơn về các quyết định thiết kế - trong những tình huống nào bạn muốn thừa kế, và vì lý do gì? Trong các ngôn ngữ động, tôi thấy một vài lý do để chọn thừa kế trên mixin, bên cạnh những gì Raynos đã mô tả. Hiệu suất của việc tạo đối tượng có thể là một lý do.
Magnus Wolffelt

@MagnusWolffelt: "trong tình huống nào bạn muốn thừa kế" Khi hai lớp thỏa mãn mối quan hệ IS-A. "Hiệu suất của việc tạo đối tượng" không phải là lý do để chọn cái này hơn cái kia. Kế thừa làm cho một tuyên bố rất mạnh mẽ về hai lớp đối tượng. Mixins làm cho một tuyên bố yếu hơn và linh hoạt hơn. Kế thừa được sử dụng khi hai lớp thỏa mãn mối quan hệ "IS-A". Tôi có thể nói gì thêm nữa? Tôi không thể hiểu câu hỏi của bạn rất tốt. Bạn có thể làm rõ những gì bạn muốn biết?
S.Lott

0

Chà, ví dụ tốt nhất tôi có thể đưa ra cho bạn là một diễn viên cho một trò chơi có sự kế thừa cho một số nội dung cơ bản nhưng sử dụng mixins / plugin cho chức năng chia sẻ. Các chức năng được chia sẻ có thể là (trực tiếp từ mã nguồn!):

var plugins = {
    SingleVisualEntity : SingleVisualEntity,
    JumpBehaviour      : JumpBehaviour,
    WeaponBehaviour    : WeaponBehaviour,
    RadarBehaviour     : RadarBehaviour,
    EnergyGatherer     : EnergyGatherer,
    LifeBarPlugin      : LifeBarPlugin,
    SelectionPlugin    : SelectionPlugin,
    UpgradePlugin      : UpgradePlugin,
    BrainPlugin        : BrainPlugin,
    PlanetObjectPlugin : PlanetObjectPlugin,
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.