2012-06-22 4 views
17

Tôi vừa mới vượt qua thừa kế con rối gần đây. Một số câu hỏi xung quanh nó:thừa kế con rối VS thành phần con rối

  1. thực hành tốt có sử dụng thừa kế con rối không? Tôi đã được một số đồng nghiệp giàu kinh nghiệm thừa nhận Sự thừa kế trong con rối không phải là rất tốt, tôi không hoàn toàn bị thuyết phục.

  2. Đến từ thế giới OO, tôi thực sự muốn hiểu dưới trang bìa, cách thức hoạt động thừa kế của con rối, cách hoạt động của tác giả cũng như thế nào.

Trả lời

38
  1. Điều đó phụ thuộc, như có hai loại thừa kế và bạn không đề cập mà bạn có ý nghĩa.

    1. Thừa kế mã: kế thừa từ một định nghĩa node fqdn { } khác. Điều này đặc biệt được khuyến khích mạnh mẽ chống lại, bởi vì nó có xu hướng thất bại the principle of least surprise. Các ví dụ điển hình mà bắt người dân ra là thế này:

      node base { 
          $mta_config = "main.cf.normal" 
          include mta::postfix # uses $mta_config internally 
      } 
      node mailserver inherits base { 
          $mta_config = "main.cf.mailserver" 
      } 
      

      Biến $mta_config được đánh giá trong phạm vi cơ sở, do đó, "ghi đè" đang được cố gắng trong mailserver không hoạt động.

      Không có cách nào để trực tiếp tác động đến nội dung trong nút chính, do đó, có rất ít lợi ích so với bố cục. Ví dụ này sẽ được cố định bằng cách loại bỏ thừa kế và bao gồm mta::postfix (hoặc một lớp "chung"/"cơ sở" khác) từ cả hai. Sau đó, bạn có thể sử dụng parameterised classes.

    2. Thừa kế lớp: sử dụng cho kế thừa lớp là bạn có thể ghi đè tham số trên tài nguyên được xác định trong lớp cha. Thực hiện lại ví dụ trên theo cách này, chúng tôi nhận được:

      class mta::postfix { 
          file { "/etc/postfix/main.cf": 
          source => "puppet:///modules/mta/main.cf.normal", 
          } 
          service { ... } 
      } 
      
      class mta::postfix::server inherits mta::postfix { 
          File["/etc/postfix/main.cf"]: 
          source => "puppet:///modules/mta/main.cf.server", 
          } 
          # other config... 
      } 
      

      Điều này có hiệu quả, nhưng tôi muốn tránh nhiều cấp độ thừa kế sâu vì nó trở nên nhức đầu để duy trì.

    3. Trong cả hai ví dụ này, chúng dễ dàng được cải thiện bằng cách chỉ định dữ liệu trước (qua ENC) hoặc truy vấn dữ liệu nội tuyến qua extlookup hoặc hiera.

  2. Hy vọng các ví dụ trên sẽ hữu ích. Thừa kế lớp chỉ cho phép ghi đè các tham số - bạn không thể xóa các tài nguyên được xác định trước đó (một câu hỏi phổ biến). Luôn tham chiếu đến tài nguyên có tên loại được viết hoa (file { ..: } sẽ trở thành File[..]).

    Cũng hữu ích là bạn cũng có thể xác định các tham số là undef, có hiệu quả làm mất chúng.

3

Lúc đầu, tôi chỉ xác định sự khác biệt giữa hai, Thừa kế là mối quan hệ "là-a" và Thành phần là mối quan hệ "có-a".

1) Trong thừa kế con rối là thừa kế đơn có nghĩa là, chúng tôi không thể lấy được từ nhiều hơn một lớp. Thừa kế là tốt trong con rối, nhưng chúng ta nên biết nơi nó được áp dụng.Ví dụ, docs Múa rối phần [ "Ngoài: Khi nào thì Inherit" tại liên kết này https://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#aside-when-to-inherit], Họ thực sự đặt tên chính xác hai tình huống mà thừa kế nên xảy ra:

  • khi bạn muốn ghi đè lên một tham số của một tài nguyên quy định tại lớp mẹ
  • khi bạn muốn kế thừa từ một lớp các thông số cho tham số tiêu chuẩn đánh giá cao

Nhưng xin lưu ý một số điều quan trọng ở đây:

2) Mặt khác, thành phần là kỹ thuật thiết kế để thực hiện mối quan hệ có. mà chúng tôi có thể thực hiện bằng cách sử dụng bao gồm từ khóa bù nhìn và cũng có thể, với lớp {'baseclass':}, sau đó, nếu bạn muốn sử dụng thông số.

(Xin lưu ý: Trong con rối, chúng ta có thể sử dụng "bao gồm" nhiều lần nhưng không phải là "lớp học" cú pháp, như con rối sẽ phàn nàn với các định nghĩa lớp trùng lặp)

Vì vậy, đó là (hoặc thừa kế hoặc bố cục) tốt hơn để sử dụng trong Puppet: Nó phụ thuộc vào ngữ cảnh tôi muốn nói, mã con rối bạn đang viết vào lúc này và hiểu được những hạn chế của sự thừa kế con rối và khi nào sử dụng bố cục.

Vì vậy, tôi sẽ cố gắng giữ tất cả điều này trong vài điểm:

1) Lúc đầu, con rối sử dụng mô hình thừa kế duy nhất.

2) Trong con rối, sự đồng thuận chung quanh thừa kế là để chỉ sử dụng nó khi bạn cần phải kế thừa giá trị mặc định từ cơ sở/Phụ huynh

3) Tuy nhiên, nhìn vào vấn đề này, nơi bạn muốn kế thừa giá trị mặc định từ cha mẹ:

class apache { 
} 

class tomcat inherits apache { 
} 

class mysql inherits tomcat { 
} 

class commerceServer inherits mysql { 
} 

Thoạt nhìn, điều này có vẻ hợp lý nhưng lưu ý rằng mô-đun MySQL hiện đang kế thừa các giá trị mặc định và tài nguyên từ lớp tomcat. Điều này không chỉ làm cho không có ý nghĩa như các dịch vụ này là không liên quan, nó cũng cung cấp một cơ hội cho những sai lầm để kết thúc trong các biểu hiện rối của bạn.

4) Vì vậy, cách tiếp cận tốt hơn là chỉ cần thực hiện bao gồm trên mỗi lớp (ý tôi là thành phần) bạn muốn sử dụng, vì điều này loại bỏ mọi vấn đề phạm vi của bản chất này.

Kết luận: Chúng tôi có thể thử và đơn giản hóa các biểu hiện rối bằng cách sử dụng thừa kế, điều này có thể là đủ, nhưng nó chỉ có thể làm việc đến một điểm.Nếu môi trường của bạn phát triển lên hàng trăm hoặc thậm chí hàng nghìn máy chủ, chiếm hơn 20 hoặc 30 loại máy chủ khác nhau, một số có thuộc tính được chia sẻ và sự khác biệt tinh tế, trải rộng trên nhiều môi trường, bạn có thể sẽ gặp phải một trang web lộn xộn không thể quản lý mô-đun được kế thừa. Tại thời điểm này, sự lựa chọn hiển nhiên là thành phần.

Go qua những liên kết này, nó giúp chúng ta hiểu phần bù nhìn và kế thừa một cách tốt (cá nhân họ đã giúp tôi):

  1. Thiết kế Múa rối - Đó là thực sự tốt, http://www.craigdunn.org/2012/05/239/
  2. link Wiki: http://en.wikipedia.org/wiki/Composition_over_inheritance
  3. Modeling Lớp phần với lớp parametrized: https://puppetlabs.com/blog/modeling-class-composition-with-parameterized-classes

tôi cơ bản là một lập trình viên, cá nhân một người ủng hộ mạnh mẽ của Inversion of Control/Dependency Injection, đó là khái niệm/mẫu có thể có thể thông qua thành phần.