On Jan 30, 2013, at 9:31 AM, jcbollinger <john.bollin...@stjude.org> wrote:

> 
>> I'm not sure I fully agree with this from a design standpoint. In 
>> object-oriented programming, one of the design principles is that variables 
>> relating to the object are encapsulated within the object and exposed or not 
>> depending on how they should be accessed.
>> 
> 
> Indeed so.  Do be aware, however, that Puppet DSL is not an object-oriented 
> language.  Among other things, it has no language-enforced encapsulation at 
> all, and Puppet "classes" are not classes in the OO sense of the term.  
> Puppet has no accessor methods (or any methods at all, actually), so the only 
> external interface that modules can provide consists of the data relied upon 
> and and declared by the module.
> 
> Inasmuch as one can apply OO principles even in contexts that are not 
> natively OO, however, my advice cleaves closely to OO orthodoxy by 
> recommending well-defined and documented component interfaces and 
> discretionary observation of encapsulation (since the language won't enforce 
> it).  The only way to adhere more strictly to OO principles would be for 
> modules to avoid relying on each others' data at all.  That's a nice ideal, 
> but it is often not practical to apply as an absolute requirement.  Such a 
> recommendation would not have been responsive to the question, anyway.
> 

I'm aware that Puppet DSL is much more declarative than OO, but in this 
particular light there is a lot of cosmetic lip-service to typical OO design - 
classes, inheritance (though limited), paramerterized instantiation of classes 
- which is why I brought that up. I'm fine with using those concepts and what 
their limitations are in the Puppet implementation. I'm also not advocating to 
adhere more strongly to OO ideals. At the end of the day, Puppet, for me at 
least, is a configuration management system. In that light it is more critical 
for me that it do that well than adhere to some design principle rigidly just 
because. And one of the things that makes a good config mgmt system work well 
is reducing the duplication of data that can cause inconsistencies. If a rigid 
adherence to OO (or declarative or imperative or whatever) design principles 
makes that hard or impossible, it should be carefully examined. A huge way I've 
seen config mgmt break down is when data is duplicated in multiple places and a 
need to change or update that data is needed and one or two spots are forgotten 
about making things break or behave badly causing me more time debugging what 
should have been a simple (and consistent) change.
 
>> IMHO, it also makes it more obfuscated when you're accessing say the SSL CA 
>> cert path variable and that's in some 'common' module that everything has to 
>> include.
>> 
> 
> If OO is the ideal design approach (which is not at all clear, but you 
> brought it up) then it would dictate that related data be grouped into 
> objects.  That's the most fundamental and incontrovertible principle of OO -- 
> you can have OO without inheritance, without polymorphism, even without 
> enforced encapsulation, but you can't have it without objects.
> 
> Puppet's analogs of objects are classes and resources.  Ergo, if one wants to 
> pursue an OO strategy then classes should contain and own their own data.
> 
> More generally, modules aren't modular if they have to rely on all their data 
> being provided by some other module.  Nevertheless, it doesn't really matter 
> which class in which module is documented to provide the data of interest.  
> As long as the module documents it and commits to those details remaining 
> stable, it amounts to the same thing I described.
> 
 
Agreed (See above), but if every module has to define ssl_ca_path every time 
they need it, I don't want that methodology because when I need to change or 
update ssl_ca_path, I need to remember every module that defined and update it 
instead of updating in the one location that all dependent modules pull from. 
Sure I can define all this in one common module that every module that has a 
'public' variable places stuff in, or I can define it in hiera and every module 
pulls it from there (though there are inheritance issues there that makes it 
less ideal), but at the end of the day I think we agree you should pick a 
method, document it, and stick to it.

>> Granted it makes it easier on the module developer - just always in include 
>> the common module and your variables should be there - but it also makes it 
>> less explicit. I would argue, if you're writing a module that depends on 
>> using the SSL CA cert path you have some dependency on the SSL module and 
>> should have some understanding of what that module does and the 
>> ramifications of using that module, so you should explicitly include that 
>> module for that dependency. In just about every language you must include 
>> the external modules/libraries you depend on for functionality outside the 
>> standard norm. In puppet the standard norm - the stdlib.h equivalent if you 
>> will - I would consider to be facter variables. You want to use LDAP or SSL 
>> or Kerberos? You best include those modules explicitly and figure out what 
>> you can use from them - ldap.h <> ldap::params, ssl.h <> ssl::params, etc. 
>> Standardize how you create these public puppet 'headers' and use them 
>> explicitly and appropriately that way.
>> 
> 
> And now that you drop the idea of a common data module, we come back around 
> to using other modules' classes' variables.   Are you honestly arguing that 
> it is better to analyze class implementations and pull out variables 
> willy-nilly than to define and rely on documented interfaces?  I think you 
> owe a penance at the OO altar.
> 

I'm arguing that no more than I would argue having to delve into the source 
code of openssl in order to use it in my C program - that's what the header is 
for. I'm arguing to define your class implementations such that the nitty 
gritty of that class' implementation need not be inspected in order for another 
module to make use of it, not mash all the public bits in to one globally 
public class that has no nitty gritty bits to implement. In my example 
<module>::params is considered the header for the module (granted a header that 
exposes values, but that can't be helped due to the declarative nature of the 
DSL). There should be no implementation in that sub-module and even <module> 
should reference that 'header' to get the variables it needs to do its work. 
But I'll still pay penance at the OO altar for all my past transgressions 
against and abuses of it.

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to puppet-users+unsubscr...@googlegroups.com.
To post to this group, send email to puppet-users@googlegroups.com.
Visit this group at http://groups.google.com/group/puppet-users?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to