-
Notifications
You must be signed in to change notification settings - Fork 2
Discussion Questions
See also: Russ Olsen interview on Ruby Rogues (there were some questions about DPiR, from the beginning until about 6-7 minutes in, and perhaps later)
- Regarding the C OOP analogy, Linus Torvalds is an OOP naysayer, but has made highly reliable (and maintainable?) code. What does this say about OOP? benjaminoakes
- I think it means OOP is not the only way to do it. You can write poetry in French or English. danbernier
- For the curious: Panel: Objects on Trial is supposed to be a funny but serious look at oop in general. Best point made for me is that you don't need O.O. based language to create an O.O. system. diego
- Is it bad to use patterns as more than a vocabulary? Should they only be "rediscovered"? benjaminoakes
- Is DRY an antipattern? Is it over-applied or often prematurely applied? benjaminoakes
- Is YAGNI an antipattern? Is it over-applied or often prematurely applied? danbernier
- Does Ruby hide too much complexity? Is there too much magic in, say, how mixins work? For example, the equivalent in JavaScript is as expressive, but less "magical". benjaminoakes
- What's the equivalent in JavaScript? Something like
a.extend(b)
? or do you mean the prototype object model? danbernier - As an engineer, shouldn't you know how your plumbing works? benjaminoakes
- Yes, but how far down? Do engineers need to understand quarks? danbernier
- How does the problem domain affect the use of patterns? How about culture of an organization? benjaminoakes
- I think the architecture affects it more than the problem domain. Web apps have similar patterns regardless of problem domain, and same goes for rich-client 3D simulations, rich-client GUI apps, web service layers, and language parsers. danbernier
- How does your organization's culture view pattern use? Do they have a bad name (e.g. from being over-applied)? benjaminoakes
This chapter is Ruby basics. If anyone has any clarifying questions, we'll be happy to clear things up.
- Coming from statically typed languages like Java and C, I still don't fully understand how the ruby interpreter handles all
@instance_variable
's. How exactly does the interpreter pick up all of them? Zach - I'm not sure what part is unclear to you, but basically, the syntax (something like
/\b@[a-z_]+\b/
) makes them easy enough to recognize. The main difference is that Ruby lets you add new instance variables at run-time (see https://gist.github.com/1579738: first,f
has no@bonk
, then later, it does). Think of it like a hash, where the key is the instance variable's name, and you can add new keys. danbernier - To expand on @danbernier's explanation: are you familiar with how
this
is bound in JavaScript? How aboutthis.variable = 'value'
? The latter is essentially the same idea as@variable = 'value'
in Ruby.
From Wikipedia:
The control structure (inversion of control) that is the result of the application of a template pattern is often referred to as the Hollywood Principle: "Don't call us, we'll call you."
- When have you found yourself using Template before? benjaminoakes
- When have you wished you hadn't used Template before? benjaminoakes
- One thing I find tricky about the Template Method pattern is picking methods to "punch out" of the template, in a way that makes sense. If you pick strictly the things that vary, it's an effective solution, but it might not be the clearest; and as the code ages & changes, you might need to refactor the lines of the template methods. Maybe this is an argument for keeping use of the template method small. I'll try to think up a good example. danbernier
- Is Template limited in its usefulness? As @danbernier points out, it's more useful when there are fewer things that vary. The example of
initialize
in Ruby being a hook method is one example (only one method, but look at how much you can do with it). benjaminoakes - Is Ruby's
Object
a good example of when inheritance makes sense (in conjunction with theinitialize
hook)? If so, what does that mean forBasicObject
? benjaminoakes
- When have you found yourself using Strategy before? benjaminoakes
- When have you wished you hadn't used Strategy before? benjaminoakes
- When is Template a better choice? benjaminoakes
- How does your favorite library use Strategy well? Poorly?
- Guidelines for teasing out a Strategy? Go just far enough to get you where you need to go?
-
raise NotImplementedError
vsraise "not implemented"
benjaminoakes - When sharing data (context), what factors into your decision of how much context to share? There are two extremes:
self
vs an object tailor-made for this context. What are the pros and cons to each approach? benjaminoakes - Pros/cons of passing
self
? - How does your data-sharing mindset relate to how you use templating systems such as ERB? Or others such as Mustache? benjaminoakes
- How would you switch at runtime based on input? Metaprogramming? A lookup table?
if
/case
? - Duck typing: are superclasses good as documentation? Good enough to keep around? What are alternatives (e.g. documentation style)?
- How does passing a
Proc
limit your choices for future changes? Are they only good for when you need throwaway use cases? What could give the best of both worlds? - A crazy idea that I haven't tested: is this a better (more flexible/future-proof) alternative?
# Define method on foo
def foo.bar
# ...
end
object.do_thing_with_bar_strategy(foo)
- When have you found yourself using Observer before? benjaminoakes
- When have you wished you hadn't used Observer before? benjaminoakes
- Things mentioned in book:
- Lots of updates
- Checking for complete changes
- Handling failures
- Things mentioned in book:
- How does your favorite library use Observer well? Poorly? benjaminoakes
- How does using an observer change when multithreading? Observing over the network? benjaminoakes
- Can using an observer (and not knowing who your observers are) be too much "magic"? That is, can it make it hard to debug/tell what your dependencies are? benjaminoakes
- Guidelines for handling updates? benjaminoakes
- Is there a difference between "subscribing" and "broadcasting" (newspaper vs radio)? (E.g. another pattern that does the latter better?) benjaminoakes
- Who has used the "Publish-subscribe pattern" before? How does it relate to Observer? When would you use one over the other (advantages/disadvantages)? benjaminoakes
- From Wikipedia:
The Observer pattern is criticized[5] for being too verbose, introducing too many bugs and violating software engineering principles, such as not promoting side-effects, encapsulation, composability, separation of concepts, scalability, uniformity, abstraction, resource management, semantic distance. The recommended approach is to gradually deprecate observers in favor of reactive programming abstractions.
-
Java veterans: pain points of using the inheritance-based
java.util.Observable
? benjaminoakes - Ever found Ruby's
Observable
lacking? benjaminoakes - Why have
ActiveRecord::Observer
at all? Why not just useinclude Observable
and register your observers? How does the answer change with and without a SQL backend in the picture? NoSQL? benjaminoakes - Related REXML/EventMachine discussion? benjaminoakes
- When have you found yourself using Composite before? benjaminoakes
- When have you wished you hadn't used Composite before? benjaminoakes
- How does this help me code better? seekayel
- At what point does the Composite pattern stop? If I'm making an online forum where there are themes, topics, and posts, I could perhaps use the Composite pattern. But if I'm using a SQL database along with
ActiveRecord
is it still Composite? If it's just a bunch of loose relationships between tables? benjaminoakes - Preferring composition to inheritance: when is inheriting from
Array
a good idea? The only times I've seen it in the wild, I wish they had done composition. benjaminoakes - How flexible (able to cope with change) should your code be when determining leaves? benjaminoakes
- When is a plain tree data structure a better idea? benjaminoakes
- When have you found yourself using Iterator before? benjaminoakes
- When have you wished you hadn't used Iterator before? benjaminoakes
- Reading this chapter brought to mind Ruby 1.9's Enumerator class, "A class which allows both internal and external iteration", according to the page on ruby-doc.org. I've been unclear on exactly where one would need to use an Enumerator. I'm closer to understanding, thanks to this chapter, but I'm still curious: have any of you come across a case in which an Enumerator was the perfect object for the task? If so, what was it? cowmanifestation
- Related to cowmanifestation's question: how does Russ Olsen's discussion change with regards to Ruby 1.9? We now have
Enumerable
andEnumerator
:
Example:
ruby-1.9.2 > [].each
=> #<Enumerator: []:each>
ruby-1.9.2 > [1, 2, 3].map
=> #<Enumerator: [1, 2, 3]:map>
ruby-1.9.2 > [1, 2, 3].map.with_index { |e, i| i }
=> [0, 1, 2]
- Would it be simpler in a good way or bad way if
[].map
gave back a function rather than anEnumerator
? (E.g. like in JavaScript's[].map
) benjaminoakes - How about a parallel iterator? Like one that can take advantage of a GPU? benjaminoakes
- (yonkeltron mentioned the closely related parallel gem)
Example:
[1, 2, 3].parallel.map { |i| i * 2 } # math done in parallel, rather than sequentially
- Have you ever actually used
each_reverse
(or nowreverse_each
)? Why did you use it overreverse.each
? benjaminoakes - Is there a good middle road between internal and external iterators?
For example, wrap functions:
def smallest(enumerable)
def enumerable.each
# logic to give back the smallest, e.g. using a heap
end
enumerable
end
# Resist changes made while iterating...
def protect(enumerable)
enumerable.dup
end
a = [1, 2, 3]
# Now I can change how I iterate on the fly...
smallest(a).each { |i| ... }
protect(a).each { |i| ... }
class Foo
def bar
safe_and_sound = protect(@a)
SomeLibrary.do_something_with_enumerable(safe_and_sound)
end
end
- When have you found yourself using Command before? benjaminoakes
- When have you wished you hadn't used Command before? benjaminoakes
- How does this help me code better? seekayel
benjaminoakes:
- Is the composite command overkill? Seems like a simple script might be better.
- Undoable: If this is a requirement the this pattern makes sense.
- Undoing destructive commands: seems like this could be an error prone strategy if not done carefully.
- How does PowerShell handle this? They have cmd-lets right?
- When have you found yourself using Adapter before? benjaminoakes
- When have you wished you hadn't used Adapter before? benjaminoakes
- How does this help me code better? seekayel
benjaminoakes:
- Monkey patching? Really?
- Is duck typing a general case of Adapter in some ways?
- Why not wrap like, say, jQuery? Is monkeypatching evil?
- Is ActiveSupport a good or bad example of taking monkeypatching responsibility seroiusly?
- Why doesn't ad-hoc modification get done more? If it's because of memory, what strategies are there to mitigate the problem?
- How does testing factor into the decision of monkeypatching vs classic adapter?
- How about using a Module and including or extending to keep things neat?
- How would you go about testing the implementation of an adapter?
Design Patterns in Ruby Discussion by NewHaven.rb is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.