Подтвердить что ты не робот

Кукольное наследование В.С. кукольная композиция

В последнее время я только что получил кросс-кукольное наследование. Несколько вопросов вокруг него:

  • Хорошо ли использовать кукольное наследование? Мне рассказали некоторые из опытных марионеточных коллег. Наследование в марионетке не очень хорошее, я не был полностью убежден.

  • Из мира ОО я действительно хочу понять под прикрытием, как работает кукольное наследование, как и надменные работы.

4b9b3361

Ответ 1

  • Это зависит от наличия двух типов наследования, и вы не говорите, что вы имеете в виду.

    • Node Наследование: наследование от одного определения node fqdn { } другому. Это, в частности, настоятельно рекомендуется против, поскольку он имеет тенденцию терпеть неудачу принцип наименьшего удивления. Классический пример, который улавливает людей, таков:

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

      Переменная $mta_config оценивается в базовой области, поэтому "переопределение", которое выполняется в почтовом сервере, не работает.

      Невозможно напрямую повлиять на то, что в родительском node, так что мало пользы от композиции. Этот пример можно было бы устранить, удалив наследование и включив mta::postfix (или другой "общий" / "базовый" класс) из обоих. Затем вы могли бы использовать параметризованные классы.

    • Наследование классов: использование для наследования классов заключается в том, что вы можете переопределить параметры ресурсов, определенных в родительском классе. Переопределив приведенный выше пример таким образом, получим:

      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...
      }
      

      Это работает, но я бы избегал идти более чем на один уровень наследования, поскольку он становится головной болью для поддержания.

    • В обоих этих примерах их легко улучшить, указав данные заблаговременно (через ENC) или запросив данные inline через extlookup или hiera.

  • Надеемся, что приведенные выше примеры помогут. Наследование классов позволяет только переопределять параметры - вы не можете удалить ранее определенные ресурсы (общий вопрос). Всегда ссылайтесь на ресурс с именем заглавного типа (file { ..: } станет File[..]).

    Также полезно, что вы также можете определить параметры как undef, эффективно отключив их.

Ответ 2

Сначала я просто определяю различия между ними, Inheritance - это отношение "is-a", а "Composition" - это отношение "has-a".

1) В кукольном наследовании одиночное наследование, что означает, что мы не можем получить более одного класса. Наследование хорош в марионетке, но мы должны знать, где она применяется. Например, раздел "Кукольные документы" [ "Рядом: когда наследовать" по этой ссылке https://docs.puppetlabs.com/puppet/latest/reference/lang_classes.html#aside-when-to-inherit], они на самом деле назовите ровно две ситуации, когда наследование должно произойти:

  • когда вы хотите перезаписать параметр ресурса, определенного в родительский класс
  • если вы хотите наследовать от класса параметров для стандартных значений параметров

Но обратите внимание на некоторые важные вещи здесь:

2) С другой стороны, композиция - это метод проектирования для реализации has-a relationship. которые мы можем сделать с помощью include кукольного ключевого слова, а также с class {'baseclass':}, более поздняя версия, если вы хотите использовать параметры.

( Обратите внимание. В марионетке мы можем использовать "include" несколько раз , но не синтаксис "class" , так как марионетка будет жаловаться на двойные определения классов)

Итак, то, что (наследование или композиция) лучше использовать в Puppet: это зависит от контекста, который я имею в виду, какого кукольного кода вы пишете в данный момент и понимаете ограничения марионетки наследование и когда использовать композицию.

Итак, я постараюсь сохранить все это в нескольких точках:

1) Сначала кукольный использует одиночную модель наследования.

2) В марионетке общий консенсус вокруг наследования заключается в том, чтобы использовать его только тогда, когда вам нужно наследовать значения по умолчанию из Base/Parent

3) Но посмотрите на эту проблему, когда вы хотите наследовать значения по умолчанию от родителя:

class apache {
}

class tomcat inherits apache {
}

class mysql inherits tomcat {
}

class commerceServer inherits mysql {
}

На первый взгляд это выглядит логичным, но обратите внимание, что модуль MySQL теперь наследует значения по умолчанию и ресурсы из класса tomcat. Мало того, что это не имеет смысла, поскольку эти услуги не связаны друг с другом, это также дает возможность ошибаться в ваших манифестах марионеток.

4) Таким образом, лучший подход состоит в том, чтобы просто выполнить включение в каждый класс (я имею в виду композицию), который вы хотите использовать, поскольку это устраняет все проблемы с областью такого рода.

Вывод:. Мы можем попытаться упростить наши марионеточные манифесты, используя наследование, этого может быть достаточно, но его можно использовать только до точки. Если среда youre растет до сотен или даже тысяч серверов, состоящий из более чем 20 или 30 различных типов серверов, некоторые из которых имеют общие атрибуты и тонкие различия, распределенные по нескольким окружениям, вы, скорее всего, получите неуправляемую запутанную сеть унаследованных модулей. На данный момент очевидным выбором является композиция.

Пройдите по этим ссылкам, это помогает правильно понять марионеточную композицию и наследование (лично они мне помогли):

Я в основном программист, лично сильный сторонник Inversion of Control/Dependency Injection, который представляет собой концепцию/шаблон, который может быть возможен через композицию.