Is this a kind of design patterns?

Hi!

Sometimes a class provides object instantiation methods other than new.
See an example.

class Color
def initialize r, g, b
@r = r
@g = g
@b = b
end

def to_s
    "R: #{@r}, G: #{@g}, B: #{@b}"
end

class << self
    def red
        new 255, 0, 0
    end

    def blue
        new 0, 0, 255
    end

    def green
        new 0, 255, 0
    end
end

end

puts Color.new(100, 120, 140)
puts Color.red
puts Color.blue

Is this one of design patterns, or just a simple idiom?
It’s similar to a factory method pattern but it’s not according to the
definition.
Is there any name for it?

TIA.

Sam

Sam K. wrote:

end
    def blue

puts Color.red
Sam

isn’t that the facory design pattern ?

The truth is, as a ganeral rule the original G4 design patterns were
kinda
statically-typed-language-centric, so it wouldn’t surprise me if there
was
some small details in Ruby versions of the patterns that didn’t quite
fit
the “classic” description.

In this case though, it does look a lot like the Factory pattern, apart
from
new still being available. I think if Color.new was re-declared as
private,
that would make it a textbook case of the Factory pattern.

IANA(language)L though…

;Daniel

On 22/03/06, killy-kun [email protected] wrote:

    @g = g
    end

TIA.

Sam

isn’t that the facory design pattern ?


Daniel B.
http://danielbaird.com (TiddlyW;nks! :: Whiteboard Koala :: Blog ::
Things
That Suck)
[[My webhost uptime is ~ 92%… if no answer pls call again later!]]

Sam K. wrote:

end
    def blue

puts Color.red
puts Color.blue

Is this one of design patterns, or just a simple idiom?
It’s similar to a factory method pattern but it’s not according to the
definition.
Is there any name for it?

Since you invoke a class’s method “new” like any other method of any
other object (no special syntax) you can say with some justification
that all classes are basically factories.

IMHO your example is not optimal because it wastes resources. Since
Color is immutable anyway constants seem a better choice:

Color = Struct.new :r, :g, :b
class Color
def to_s
sprintf “R: 0x%02x, G: 0x%02x, B: 0x%02x”, self.r, self.g, self.b
end

RED = new 0xFF, 0x00, 0x00
BLUE = new 0x00, 0x00, 0xFF
GREEN = new 0x00, 0xFF, 0x00
end

Kind regards

robert

On 3/22/06, Sam K. [email protected] wrote:

end
    def blue

puts Color.red
puts Color.blue

Is this one of design patterns, or just a simple idiom?
It’s similar to a factory method pattern but it’s not according to the
definition.
Is there any name for it?

That’s the “Factory Method” pattern. It’s handy when you want
SomeClass.new to return an instance of SomeOtherClass, or just when
you want things to be easier to read.

One of my favorite examples (I think this is a Martin F. trick) is:
some_date = december(10,2006)

Robert K. wrote:

    @b = b

puts Color.new(100, 120, 140)
other object (no special syntax) you can say with some justification

RED = new 0xFF, 0x00, 0x00
BLUE = new 0x00, 0x00, 0xFF
GREEN = new 0x00, 0xFF, 0x00
end

This looks tricky and wonderful.
I just tried to make a simple example which was not intended to be
ooptimal.
I will apply your way when I need to make a real code.:slight_smile:
Thank you.

Sam

Wilson B. wrote:

That’s the “Factory Method” pattern. It’s handy when you want
SomeClass.new to return an instance of SomeOtherClass, or just when
you want things to be easier to read.

One of my favorite examples (I think this is a Martin F. trick) is:
some_date = december(10,2006)

At first I thought so.
But the definition of “Factory Method Pattern” bothered me.
The definition of “Factory Method Pattern” is:

"Define an interface for creating an object, but let subclasses decide
which class to instantiate. Factory Method lets a class defer
instantiation to subclasses. "

However, in my Color example, there’s no subclassing involved.
So the class itself is a factory as well as the product that the
factory makes.
Do you think that we can still call it “Factory Method Pattern”?

Sam

my personal definition:

factory method:
method, that creates a object,
because new(…) is not sufficient
in that case

imho there’s too much babbling about design patterns und too
little pragmatism. who cares if it’s pattern #1 or pattern #2.

it’s more a matter of good taste as a matter of applying rules.

especially in java I have seen ridiculous numbers of classes doing
trivial stuff using factories, abstract classes, interfaces, proxies,
adapters, delegates and the like. it’s often considered by so called
architects to be good software if it uses several design pattern
no matter what for…

Robert K. wrote:

Sam K. wrote:

end
    def blue

puts Color.red
puts Color.blue

Is this one of design patterns, or just a simple idiom?
It’s similar to a factory method pattern but it’s not according to the
definition.
Is there any name for it?

Since you invoke a class’s method “new” like any other method of any
other object (no special syntax) you can say with some justification
that all classes are basically factories.

IMHO your example is not optimal because it wastes resources. Since
Color is immutable anyway constants seem a better choice:

Color = Struct.new :r, :g, :b
class Color
def to_s
sprintf “R: 0x%02x, G: 0x%02x, B: 0x%02x”, self.r, self.g, self.b
end

RED = new 0xFF, 0x00, 0x00
BLUE = new 0x00, 0x00, 0xFF
GREEN = new 0x00, 0xFF, 0x00
end

I was thinking along the same lines, but I do like the method interface
(e.g. Color.red over Color::RED). My suggestion would have been
something like:

class Color

class << self
def red
@red ||= new 255, 0, 0
end

end
end


– Jim W.

Peter E. wrote:

it’s more a matter of good taste as a matter of applying rules.

especially in java I have seen ridiculous numbers of classes doing
trivial stuff using factories, abstract classes, interfaces, proxies,
adapters, delegates and the like. it’s often considered by so called
architects to be good software if it uses several design pattern
no matter what for…

You may be right.
However, knowing the right definition is important for communcation.
If somebody tells you to make a class using “X” pattern, you need to
understand what “X” pattern means.
The pattern names might have been arbitrarily made but now it’s very
common almost like a standard.

Sam

Peter E. wrote:

imho there’s too much babbling about design patterns und too
little pragmatism. who cares if it’s pattern #1 or pattern #2.

The value of patterns is the vocabulary it gives to developers.

it’s more a matter of good taste as a matter of applying rules.

especially in java I have seen ridiculous numbers of classes doing
trivial stuff using factories, abstract classes, interfaces, proxies,
adapters, delegates and the like. it’s often considered by so called
architects to be good software if it uses several design pattern
no matter what for…

Ahh, now this I agree with. People get it in their heads that patterns
are good, what they forget is that every pattern solves a given problem
with a set of tradeoffs. Understanding the tradeoffs is crucial to
fully understanding the pattern. Too many people blindly apply the full
blown pattern right out of the GOF book without considering the costs.

Beware of programmers who have just learned a new pattern and are
looking for a place to apply it.


– Jim W.

On 3/22/06, Jim W. [email protected] wrote:

end
Is there any difference between the above code and this?

class Color

def self.red
@red ||= new 255, 0, 0
end

end

Wilson B. wrote:

On 3/22/06, Sam K. [email protected] wrote:

Is this one of design patterns, or just a simple idiom? […]

That’s the “Factory Method” pattern. It’s handy when you want
SomeClass.new to return an instance of SomeOtherClass, or just when
you want things to be easier to read.

Hmmm … It’s not the GOF Factory Method pattern. It doesn’t even solve
the same problem that the Factory Method pattern is designed to address.

But it is a useful technique … pattern or not.


– Jim W.

Jim W. wrote:

definition.
def to_s
something like:

class Color

class << self
def red
@red ||= new 255, 0, 0
end

end
end

IMHO this is not thread safe. If you need the method interface, you
could do something like

class Color
def self.method_missing(s,*a,&b)
if a.empty? && b.nil?
const_get s.to_s.upcase
else
super
end
end
end

:slight_smile:

robert

Jim W. wrote:

definition.
def to_s
something like:

class Color

class << self
def red
@red ||= new 255, 0, 0
end

end
end

And this is tantamount to dependency injection. For example, with my
mindi framework (findable on RAA), there is the
examples/color-namespace.rb:

require ‘mindi’

class PictureApp
include MinDI::InjectableContainer

class Picture
attr_reader :opts
def initialize(opts)
@opts = opts
end
end

class Color < Struct.new(:r, :g, :b)
def +(color)
Color.new(r + color.r, g + color.g, b + color.b)
end
end

class ColorNamespace
include MinDI::InjectableContainer

red     { Color.new(1,0,0) }
green   { Color.new(0,1,0) }
yellow  { red + green      }

end

colors { ColorNamespace.new }
picture { Picture.new(:background => colors.yellow) }
end

pic_app = PictureApp.new
pic = pic_app.picture
raise unless pic.opts[:background] == pic_app.colors.yellow

let us wrap
const_get

begin
const_get(…)
rescue NameError
super(…)
end
in order to get NoMethodError instead of a NameError

Cheers
Robert
On 3/23/06, Robert K. [email protected] wrote:

Is this one of design patterns, or just a simple idiom?
Color = Struct.new :r, :g, :b
I was thinking along the same lines, but I do like the method interface
end
super
end
end
end

:slight_smile:

    robert


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

On 3/22/06, Mark V. [email protected] wrote:

  ...
 ...

end

No, not at my knowledge

R. Mark V.
Object Computing, Inc.


Deux choses sont infinies : l’univers et la bêtise humaine ; en ce qui
concerne l’univers, je n’en ai pas acquis la certitude absolue.

  • Albert Einstein

Jim W. wrote:

Robert K. wrote:

IMHO this is not thread safe. If you need the method interface, you
could do something like
[…]
:slight_smile:

I did catch the smiley. :slight_smile:

:slight_smile:

class << self

:wink:

:slight_smile:

Since we’re in Color anyway, you can simplify the definition that by

class Color
# …
class << self
private
def define(name, *args)
cname = name.to_s.upcase
col = const_set( cname, new(*args))
class_eval “def self.#{name}; #{cname}; end”
end
end

 define :red, 255, 0, 0
 # ...

end

:slight_smile:

Kind regards

robert

Robert K. wrote:

IMHO this is not thread safe. If you need the method interface, you
could do something like
[…]
:slight_smile:

I did catch the smiley. :slight_smile:

Given that the original returned a new object on every invocation, a
race condition that might generate an extra light weight object or two
at initialization seems to be a low risk.

However, if I were really concerned about the race condition, I think I
would go the metaprogramming route rather then the dynamic lookup route.
Something more like this:

class Color

class << self
private
def define(name, color)
class_eval “#{name.to_s.upcase} = color”
class_eval “def Color.#{name}; #{name.to_s.upcase}; end”
end
end

define :red, Color.new(255, 0, 0)
...

end

:wink:


– Jim W.

Robert K. wrote:

Since we’re in Color anyway, you can simplify the definition that by

I like that.

And I love the collective refactoring that goes on in this list!


– Jim W.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs