From: Jamis Buck Date: 2004-11-14T14:13:38+09:00 Subject: Re: [ANN] Copland to Needle article on RubyGarden (LONG) Joel VanderWerf wrote: > In this case there are just a few kinds, but what if the printer > arguments have more possible variation? What if, in addition to kind, > there is an integer argument (a port number, say)? Well... you'd just use an array for the hash key, right? Or am I misunderstanding your question? > It seems like private services would be awkward to implement in Needle, > at least with the hash-based interface. (With the method sending > interface, I guess you could just declare it private in the same way.) > Thoughts? I've thought about this. Copland supports the concept of a private service, but I'm not sure how to implement the same thing in Needle. The tricky part is that currently, Needle can't really detect whether a service is being requested by another service in the same container, or by a service in a different container. I would very much like to support private/public services in Needle, but I just haven't seen my way clear on how to do it, yet. > >> However, you could also create a service factory. It would do just as >> you did, with a Hash for caching created instances. >> >> class Printer >> def self.get( name ) >> @printers ||= Hash.new >> @printers[ name ] ||= new( name ) >> end >> >> private_class_method :new >> def initialize( name ) >> ... >> end >> end >> >> reg.define.printers { Printer } >> >> p1 = reg.printers.get( :monochrome ) >> p2 = reg.printers.get( :monochrome ) >> assert_same p1, p2 > > > This feels like it breaks encapsulation: the Printer class shouldn't > know about the service model that the container is using for it. In this > case, the service model may be an unavoidable consequence of how the > Printer class works, and so it should be enforced by the class itself. The Printer class doesn't know about its service model. Am I misunderstanding you? What in the code given above causes you to think that the service model is known to the Printer class itself? Incidentally, because the class itself IS the service, service models are actually rather inconsequential. Ignoring that fact, however, you could do the following and the Printer class would have no knowledge of which model was being used for it: reg.define do |b| b.printers1( :model => :prototype ) { Printer } b.printers2( :model => :threaded ) { Printer } b.printers3( :model => :singleton_deferred_initialize ) { Printer } ... end > > But there are classes that could be used with different service models > in different coexisting containers: a general log class that, in one > container, is threaded, but in another container is managed by a > multiton service whose keys are log type, (e.g. :security, :information, > :warnings, and :errors). Very true. >> In fact, this is almost exactly how the log-factory service in Needle >> works, although the LogFactory is a distinct class from the Logger. >> >> I'm still thinking through how to implement something like this in >> Needle itself. It'll probably wind up being, as you suggested, a >> pipeline element of some sort, although the parameterization issue >> goes a bit deeper. > > > I'm looking forward to watching Needle evolve. So am I. :) You bring up some very interesting points. I'm glad there are people that are challenging my assumptions. - Jamis -- Jamis Buck jgb3@email.byu.edu http://www.jamisbuck.org/jamis