Do I overuse class methods?

Hello,
I write in ruby for few weeks and I have noticed that in ruby I use
class (static) methods more often than in “traditional” languages like
java or c#. In java I use instance methods for two purposes -
maintaining object state and to use polymorphic behaviour. In ruby
polymorphism is available to class methods as well as for instance ones
so I don’t see need for using instance methods in stateless classes (for
example typical application / domain services).

It is common for ruby programmers or maybe I have miss something?

Best Regards,
Michał

On 2010-06-13 10:27:48 -0700, Michał Zając said:

Best Regards,
Michał

Classes are designed to instantiate objects. If you have classes that
consist solely of class methods then they aren’t functioning as classes
at all but rather as convenient globally-available namespaces for
singleton methods, which is a very procedural style of progrmaming.
Procedural programming is not necessarily bad, but you are missing out
on a great deal of the power and flexibility of an OOP langauge by
writing procedural code.

Then again, if the system works for you and maintainability and other
core values do not appear to suffer, who’s to say you’re doing it
wrong? Even asking the question shows that you’re thinking critically
about the tradeoffs involved here, which is a good start.

2010/6/14 Rein H. [email protected]:

It is common for ruby programmers or maybe I have miss something?

Classes are designed to instantiate objects. If you have classes that
consist solely of class methods then they aren’t functioning as classes at
all but rather as convenient globally-available namespaces for singleton
methods, which is a very procedural style of progrmaming. Procedural
programming is not necessarily bad, but you are missing out on a great deal
of the power and flexibility of an OOP langauge by writing procedural code.

As a compromise Michael could use module Singleton and thus define
instance methods without the overhead of creating new instances all
the time.

irb(main):001:0> require ‘singleton’
=> true
irb(main):002:0> class Foo;end
=> nil
irb(main):003:0> (1…3).map { Foo.new }
=> [#Foo:0x1029b494, #Foo:0x1029b478, #Foo:0x1029b45c]
irb(main):004:0> class Foo; include Singleton; end
=> Foo
irb(main):005:0> (1…3).map { Foo.new }
NoMethodError: private method new' called for Foo:Class from (irb):5:in block in irb_binding’
from (irb):5:in each' from (irb):5:in map’
from (irb):5
from /opt/bin/irb19:12:in `’
irb(main):006:0> (1…3).map { Foo.instance }
=> [#Foo:0x10268b88, #Foo:0x10268b88, #Foo:0x10268b88]
irb(main):007:0>

Singleton pattern allows for easier migration if at a later point in
time instances need state.

Then again, if the system works for you and maintainability and other core
values do not appear to suffer, who’s to say you’re doing it wrong? Even
asking the question shows that you’re thinking critically about the
tradeoffs involved here, which is a good start.

Absolutely agree!

Kind regards

robert

W dniu 2010-06-14 15:33, Robert K. pisze:

As a compromise Michael could use module Singleton and thus define
instance methods without the overhead of creating new instances all
the time.

I think this is interesting idea.
I have spent much time in Java / C# environments with heavy use of
dependency injection pattern so maybe this is source of my aversion to
stateless classes manual instantiation - usually something else has done
it for me :smiley: Using Singleton pattern is more similar to Service Locator
but it may be good alternative.

Thanks

On 2010-06-14 10:35:10 -0700, Michał Zając said:

stateless classes manual instantiation - usually something else has
done it for me :smiley: Using Singleton pattern is more similar to Service
Locator but it may be good alternative.

Thanks

Ruby’s design patterns (in the Gang of Four sense) are extremely
lightweight compared to their Java equivalents. Rick Olsen’s Design
Patterns in Ruby book shows good idiomatic Ruby implementations of the
GoF patterns. That said, I don’t think you want a Pattern at all. I
think you want a more object oriented architecture.

IRT Singleton: I think that Singleton is just a way to cheat and get
global state that looks like instances. I didn’t present it as a
solution because (imo) it’s really just a restatement of the problem. I
try to avoid it for the same reasons that I try to avoid the classes
you’re asking about. Let me put it this way: replace all of your
pseudo-classes (these classes that don’t instantiate and are used as
singleton method holders) with this:

YourClass = Object.new

def YourClass.some_method
… do stuff …
end

… more …

This is functionally equivalent. Does this look like good Ruby code? Is
this good OO design? If not, why not? The classes you’re asking about
aren’t (functionally) classes at all: they’re just objects like this
one. You should object to them for the same reasons that you (may)
object to the above.

Also, Ruby has far better mechanisms than dependency injection. So much
so, in fact, that Rails core member and creator of two different Ruby
dep. injection libraries, Jamis B., recently gave a great talk about
why you don’t need dependency injection in Ruby. Summary is here, and
is a good read if you’re coming from heavy, “enterprisey” languages
like Java:
Buckblog: LEGOs, Play-Doh, and Programming.

Coming from a Java background, the best thing you can do is let go of
the heavy pattern-driven architectures that are common in
enterprise-land (the ServiceLocator, CachedTemplateFactoryProxyFactory,
whatever) and enjoy the freedom of working with simple, lightweight
classes and objects.

On 2010-06-16 11:48:32 -0700, Michał Zając said:

end
designed systems there is a place for stateless classes too (of course
Back to your question - maybe it is functionally equivalent of
why you don’t need dependency injection in Ruby. Summary is here, and is
a good read if you’re coming from heavy, “enterprisey” languages like
Java: Buckblog: LEGOs, Play-Doh, and Programming.

I never treat DI and automatic DI frameworks as the same thing - and I
repeat it to every programmer I am working with :slight_smile: Due to better
language mechanisms (open classes) in ruby we can make dependency
injection as described in article. What I like less is mixing business
code and collaborators construction (new calls) in one physical code
unit.

I would prefer that you use modules for “stateless classes” that you
don’t initialize. Modules are semantically for use in both “mixins” and
namespacing, and the namespacing here is an appropriate use. They also
don’t share the semantic baggage that classes do (initialization) for
this use.

W dniu 2010-06-15 01:06, Rein H. pisze:

Let me put it this way: replace all of your

This is functionally equivalent. Does this look like good Ruby code? Is
this good OO design? If not, why not? The classes you’re asking about
aren’t (functionally) classes at all: they’re just objects like this
one. You should object to them for the same reasons that you (may)
object to the above.

I can’t agree that using such classes is always bad design. In well
designed systems there is a place for stateless classes too (of course
they are in minority). They main responsibility is not to encapsulate
data but encapsulate dependencies - for example AbstractSmtpClient which
encapsulates (wrapes) concrete SMTP client implementation. In Java this
kind of encapsulation is needed to unit test classes those use SMTP
communication. But what is more important to me is responsibility
separation (SRP) - actual business code doesn’t have to create and
configure SMTP client - it just gets ready for use AbstractSmtpClient
object from outside (not necessary from heavy weight DI framework).

Back to your question - maybe it is functionally equivalent of
defining methods inline one by one but it is not eqivalent in terms of
code readability (in my “psuedo-classes” I separated code that you have
mixed in one class) in this way we can treat every program (even written
in ruby) as “functionally equivalent” of assembler or I have
misunderstood your example :smiley:

Also, Ruby has far better mechanisms than dependency injection. So much
so, in fact, that Rails core member and creator of two different Ruby
dep. injection libraries, Jamis B., recently gave a great talk about
why you don’t need dependency injection in Ruby. Summary is here, and is
a good read if you’re coming from heavy, “enterprisey” languages like
Java: Buckblog: LEGOs, Play-Doh, and Programming.

I never treat DI and automatic DI frameworks as the same thing - and I
repeat it to every programmer I am working with :slight_smile: Due to better
language mechanisms (open classes) in ruby we can make dependency
injection as described in article. What I like less is mixing business
code and collaborators construction (new calls) in one physical code
unit.