Вы сможете использовать задачу include_vars с переменной inventory_hostname или ansible_hostname . Например:
- name: Include host specific variables
include_vars: "{{ ansible_hostname }}.yml"
- name: Include host specific secret variables
include_vars: "{{ ansible_hostname }}_secret.yml"
Еще лучшим решением было бы решение проблемы пользователей, имеющих уникальные пароли на разных хостах.
Я думаю об использовании Шаблона "посетитель".
public class Car : Vehicle
{
public void Accept( IVehicleFormatter v )
{
v.Visit (this);
}
}
public class Truck : Vehicle
{
public void Accept( IVehicleFormatter v )
{
v.Visit (this);
}
}
public interface IVehicleFormatter
{
public void Visit( Car c );
public void Visit( Truck t );
}
public class VehicleXmlFormatter : IVehicleFormatter
{
}
public class VehicleSoapFormatter : IVehicleFormatter
{
}
С этим Вы избегаете дополнительного дерева наследования и сохраняете логику форматирования разделенной от Ваших классов Механизма. Offcourse при создании нового механизма необходимо будет добавить другой метод к интерфейсу Formatter (и реализовать этот новый метод во всех реализациях интерфейса средства форматирования).
Но, я думаю, что это лучше затем создает новый класс Механизма, и для каждого IVehicleFormatter Вы имеете, создаете новый класс, который может обработать этот новый вид механизма.
Другой подход должен принять модель передачи, а не модель приема. Обычно Вам нужны различные средства форматирования, потому что Вы повреждаете инкапсуляцию и имеете что-то как:
class TruckXMLFormatter implements VehicleXMLFormatter {
public void format (XMLStream xml, Vehicle vehicle) {
Truck truck = (Truck)vehicle;
xml.beginElement("truck", NS).
attribute("name", truck.getName()).
attribute("cost", truck.getCost()).
endElement();
...
где Вы вытягиваете данные из определенного типа в средство форматирования.
Вместо этого создайте агностический форматом приемник данных и инвертируйте поток, таким образом, определенный тип продвигает данные к приемнику
class Truck implements Vehicle {
public DataSink inspect ( DataSink out ) {
if ( out.begin("truck", this) ) {
// begin returns boolean to let the sink ignore this object
// allowing for cyclic graphs.
out.property("name", name).
property("cost", cost).
end(this);
}
return out;
}
...
Это означает, что Вы все еще инкапсулировали данные, и Вы просто подаете отмеченные данные к приемнику. Приемник XML мог бы затем проигнорировать определенные части данных, возможно, переупорядочить некоторые из них и записать XML. Это могло даже делегировать к другой стратегии приемника внутренне. Но приемник должен не обязательно заботиться о типе механизма, только как представить данные в некотором формате. Используя интернированные глобальные идентификаторы, а не встроенные строки помогает сдержать стоимость вычисления (только вопросы, если Вы пишете ASN.1 или другие трудные форматы).
Почему бы не сделать IXMLFormatter интерфейсом с toXML (), toSoap (), к YAML () методы и сделать Механизм, Автомобиль и Грузовик всей реализацией это? Что не так с тем подходом?
Вы могли стараться избегать наследования для своих средств форматирования. Просто сделайте a VehicleXmlFormatter
это может иметь дело с Car
s, Truck
s... Повторного использования должно быть легко достигнуть, нарубив обязанности между методами и путем выяснения хорошей стратегии отправки. Постарайтесь не перегружать волшебство; будьте максимально конкретны в именовании методов в Вашем средстве форматирования (например. formatTruck(Truck ...)
вместо format(Truck ...)
).
Только используйте Посетителя при необходимости в двойной отправке: когда у Вас есть объекты типа Vehicle
и Вы хотите отформатировать их в XML, не зная фактический конкретный тип. Посетитель самостоятельно не решает основную проблему достижения повторного использования в Вашем средстве форматирования и может представить дополнительную сложность, в которой Вы, возможно, не нуждаетесь. Правила выше для повторного использования методами (нарубивший и отправкой) относились бы к Вашей реализации Посетителя также.