Make a revised version of design patterns in ruby


#1

Ruby is highly dynamic and extensible. Ruby is duck typed. Interface
which is pervasive in Java is hard to see in Ruby. Thing changes. Many
Gangof4 design patterns handle limitations of static languages like java
and C++. So I think in Ruby, some design patterns become trivial or
irrelevent , some can be simplified a lot.
Ruby is a fully object-oriented language. If we talk about OO, we surely
concerns about design patterns.I think many of us want to see what
happens to design patterns in ruby.
And I think the best way is to check the G4 design patterns one by one
to see which one can be simplified , which one becomes trivial , or some
new ones can be introduced.
Actually, I just think it is a good idea and I am not qualified to do
that. But I think this community can do it. Anyone checks a pattern,
then post his result here. We will soon get a revised version of design
patterns in ruby. Itâ??s attractive. I hope you are instrested , your
attendance is highly appeciated.

And I will post one first, an abstract factory example, which can be
simplified a lot as following. You can see, no inheritance tree needed.

class MacWindow
def whoami; puts “A Mac window”;end
end
class MotifWindow
def whoami; puts “A Motif window”;end
end
class MacScrollbar
def whoami; puts “A Mac Scrollbar”;end
end
class MotifScrollbar
def whoami; puts “A Motif scrollbar”;end
end
class WidgetFactory
def initialize(winCls, scrollBarCls)
@winCls = winCls
@scrollBarCls = scrollBarCls
end
def makeWindow
@winCls.new
end
def makeScrollBar
@scrollBarCls.new
end
end

def testWidgetFactory
f = WidgetFactory.new(MotifWindow, MotifScrollbar)
aWin = f.makeWindow
aScrollBar = f.makeScrollBar
aWin.whoami
aScrollBar.whoami
f = WidgetFactory.new(MacWindow, MacScrollbar)
aWin = f.makeWindow
aScrollBar = f.makeScrollBar
aWin.whoami
aScrollBar.whoami
end

testWidgetFactory

result:

A Motif window
A Motif scrollbar
A Mac window
A Mac Scrollbar

Best regards,

uncutstone


#2

2006/5/18, uncutstone wu removed_email_address@domain.invalid:

Ruby is highly dynamic and extensible. Ruby is duck typed. Interface
which is pervasive in Java is hard to see in Ruby. Thing changes. Many
Gangof4 design patterns handle limitations of static languages like java
and C++. So I think in Ruby, some design patterns become trivial or
irrelevent , some can be simplified a lot.
Ruby is a fully object-oriented language. If we talk about OO, we surely
concerns about design patterns.I think many of us want to see what
happens to design patterns in ruby.

That might be an interesting thing to do.

simplified a lot as following. You can see, no inheritance tree needed.

IMHO you don’t even need a separate class. Every object that
implements #new is a factory, especially every class object is. So
storing an object somewhere and requiring that it implements new
without args is enough.

Regards

robert


#3

Robert K. wrote:

2006/5/18, uncutstone wu removed_email_address@domain.invalid:

Ruby is highly dynamic and extensible. Ruby is duck typed. Interface
which is pervasive in Java is hard to see in Ruby. Thing changes. Many
Gangof4 design patterns handle limitations of static languages like java
and C++. So I think in Ruby, some design patterns become trivial or
irrelevent , some can be simplified a lot.
Ruby is a fully object-oriented language. If we talk about OO, we surely
concerns about design patterns.I think many of us want to see what
happens to design patterns in ruby.

That might be an interesting thing to do.

simplified a lot as following. You can see, no inheritance tree needed.

IMHO you don’t even need a separate class. Every object that
implements #new is a factory, especially every class object is. So
storing an object somewhere and requiring that it implements new
without args is enough.

Yes, you are right. Class WidegetFactory is unnecessary. So an simpler
version is:
class MacWindow
def whoami; puts “A Mac window”;end
end
class MotifWindow
def whoami; puts “A Motif window”;end
end

def testAbstractFactory
aWinFactory = MotifWindow
aWin = aWinFactory.new
aWin.whoami
end

testAbstractFactory

result:
A Motif window

In fact, as the code shows, in ruby, abstract factory pattern
disappears, since a pattern always means a group of collaborative
classes or objects. I really think ruby is a magic language.

Best regards,

uncutstone


#4

removed_email_address@domain.invalid wrote:

uncutstone wu wrote:

Actually, I just think it is a good idea and I am not qualified to do
that. But I think this community can do it. Anyone checks a pattern,
then post his result here. We will soon get a revised version of design
patterns in ruby. It’s attractive. I hope you are instrested , your
attendance is highly appeciated.

http://www.rubygarden.org/ruby?ExampleDesignPatternsInRuby
http://raa.ruby-lang.org/cat.rhtml?>category_major=Library;category_minor=Design%20Patterns

Acctually, I did took a look at ExampleDesignPatternsInRuby
before. But after read the first one , abstract factory, I am skeptical
of its quality.

I quoted the code and the explanation the author made below and I will
explain my view.

class Foo; end
class Bar; end

Here is the use of the Abstract Factory pattern

def create_something( factory )
new_object = factory.new
puts “created a new #{new_object.class} with a factory”
end

Here we select a factory to use

create_something( Foo )
create_something( Bar )
Running the code above results in the output:
created a Foo with a factory
created a Bar with a factory

Q: Ummm. Seems to me that you’re specifying the concrete class name here: create_something(Foo) and
create_something(Bar). My understanding of Abstract Factory is that there’s an additional level of I>ndirection involved.
A: The create_something method is creating objects through an abstract interface and does not have >knowledge of concrete types.
The code at the top level is selecting which factory object will be used by create_something. There always >needs to be some part of
the code that creates factories, and that part needs knowledge of concrete types. The use of the >Abstract Factory method is to shield
the rest of the code from that knowledge.

I fully donâ??t agree with the authorâ??s opinion. I think what abstract
factory does is to shield clients who need create object from the
objectâ??s concrete type, but not to shield the abstract factory itself
from concrete type.
Acctually ,abstract factory will have the knowledge of the concrete type
and shield the client of abstract factory from the concrete type .

But what the code does is opposite. The abstract factory(here is
create_something) doesâ??t know concrete type, and the client will give
that info to it every time the client need a object. Itâ??s toally
misunderstanding of abstract factory.

Since the first pattern example in the article is really bad , I am
skeptical of its quality. So I think we need redo the work. That is why
I post this message.

Best regards,

uncutstone


#5

uncutstone wu wrote:

I fully donâ??t agree with the authorâ??s opinion. I think what abstract
factory does is to shield clients who need create object from the
objectâ??s concrete type, but not to shield the abstract factory itself
from concrete type.
Acctually ,abstract factory will have the knowledge of the concrete type
and shield the client of abstract factory from the concrete type .

But what the code does is opposite. The abstract factory(here is
create_something) doesâ??t know concrete type, and the client will give
that info to it every time the client need a object. Itâ??s toally
misunderstanding of abstract factory.

The way I understood the examle is that “create_something” IS the
client. It gets passed the abstract factory (parameter named factory)
and is actually shielded from the concrete class of the factory. The
example is confusing in that the client immediately passes the created
object to the calling context (which is where the concrete factory is
know), but the comments seem to make it clear the intention of the
author.

My problem with the example is that it doesn’t solve the same problem as
the classical GOF Abstract Factory pattern. In the GOF pattern, the
abstract factory is able to build a set of related classes, not just a
single class. This is used (for example) in windowing systems where you
want to be able to create a set of related widgets (e.g. GtkButton and
GtkScrollbar, or QtButton and QtScrollbar). The example completes
misses that part of the pattern.

– Jim W.


#6

Jim W. wrote:

[…] The
example is confusing in that the client immediately passes the created
object to the calling context […]

Oops, Let me correct this. I see that the create_something does not
actually return the created object. So the confusion is not that it
returns something (which it does not), but only that the name
“create_something” fooled me into thinking it did return something. I
didn’t read it closely enough.

On my second point about creating multiple types, I see the Maze example
does cover that aspect of abstract factories … at least implicitly.


– Jim W.


#7

uncutstone wu wrote:

Actually, I just think it is a good idea and I am not qualified to do
that. But I think this community can do it. Anyone checks a pattern,
then post his result here. We will soon get a revised version of design
patterns in ruby. It’s attractive. I hope you are instrested , your
attendance is highly appeciated.

http://www.rubygarden.org/ruby?ExampleDesignPatternsInRuby
http://raa.ruby-lang.org/cat.rhtml?category_major=Library;category_minor=Design%20Patterns


#8

Jim W. wrote:

The way I understood the examle is that “create_something” IS the
client. It gets passed the abstract factory (parameter named factory)
and is actually shielded from the concrete class of the factory. The
example is confusing in that the client immediately passes the created
object to the calling context (which is where the concrete factory is
know), but the comments seem to make it clear the intention of the
author.

Ah, it seems I misunderstood something. I think the name
“create_something” fools me , it sounds like a factory method. Sorry.
I suggest the author changes the name .