From: Rhino on
On Mar 16, 1:14 pm, Lew <l...(a)lewscanon.com> wrote:
> Rhino wrote:
> >>> I have a class named StringUtils containing several utility methods.
> markspace wrote:
> >> I asked aquestionlike this here long ago.  What I think now is that
> >> you almost certainly should make the class final, and all the methods
> >> static.
>
> >> If you do need to keep state, make a new class, don't reuse the
> >> StringUtils, except as a factory.
> Rhino wrote:
> > Sorry, I'm not following this strategy.
>
> > I'm not entirely sure what constitutes 'state' in this context but I
>
> Same thing it means in any other context - "state" is the aggregation
> of the observable aspects of the (class or instance) object, i.e., the
> values of its attributes, in particular, those that affect its
> behavior.
>
> markspace is telling you that if you write a class to be stateless,
> then need to add state, it's not a good idea to mingle state with a
> stateless class.  You're better off separating the behaviors into a
> stateless class and a stateful one.
>
I'm not clear on how exactly I would separate my behaviours into a
stateless class and a stateful one. Can you give me (or point me to)
an illustration of this technique? My OO theory is not that strong so
forgive me for asking something that should probably be obvious to me.

> > suspect that the Locale-specific messages I am generating may qualify.
>
> Depends on how you do it - if you store the Locale as part of the
> state, then yes, it affects things.
>
> > As I've explained in my reply to Lew's first response, I am generating
> > Locale-sensitive error messages. I have two constructors. One
>
> Constructors means no longer being all static.
>
> > constructor has no parameters and uses the default Locale; the other
> > constructor has the Locale as its parameter and generates messages
> > appropriate for that Locale. If this counts as "state" for the
>
> Is it an observable attribute of the object?
>
> Does its value affect the object's behavior in any way?
>
> Does the value persist between method calls?
>
Given that different invocations of StringUtils might choose to
generate messages in different languages, I assume the answer to your
three questions is yes.

> > purposes of our current discussion, I'm not clear on what you're
>
> State is state, purpose notwithstanding.
>
> > proposing. How do I use StringUtils as a factory to feed the new class
> > that you are suggesting?
>
> You add a factory method to create an instance of the stateful class.
>
Again, can you clarify this a bit? You don't necessarily need to write
an example; just pointing to a document or tutorial that contains an
example would be just fine. I'm not sure where to look for such a
thing.

Thank you for your patience!

--
Rhino
From: Jeff Higgins on
On 3/16/2010 1:42 PM, Rhino wrote:

>
> My StringUtils class generates a substantial number of error messages
> via the standard ResourceBundle mechanism and delivers them in a
> Locale-sensitive fashion.

How are you delivering the error messages? If you are using the
Exception mechanism can your StringUtils class method callers do their
own translation and let StringUtils do its own thing?

From: markspace on
Lew wrote:
> Rhino wrote:
>>> I'm not entirely sure what constitutes 'state' in this context but I
>
> markspace wrote:
>> It basically means "an instance variable."
>>
>
> Unless you're talking about a static variable. That's state, too.
>
> The former is instance state. The latter is class state, or "static"
> state.


Yes, but often creating a singleton object like this is pretty bad.
(Note that the normal singleton pattern actually uses instance variables
for the object state.) At least in my opinion. It's pretty difficult
to test, can't be extended and hard to use since it doesn't actually
have a constructor, just a "global state variable." Globals are bad.

public class StringUtils {

private static Locale locale;

private StringUtils() {}

public static void setLocale( Locale loc ) {
locale = loc;
}

public static String count( String s, int count ) {
...
}
...
}

This is pretty ugly design, imo. There's a few patterns it works for,
but they're not common. I don't think the OPs utility class would be a
good choice. Yes, I'm making an assumption here, but based on what he's
told us, I think it's the right assumption.
From: markspace on
Rhino wrote:

> And that's how the code was when I posted the original question....

Right, and no worries. Now that we know what you are really doing, we
can say "the original design looks ok."

To summarize the opinions presented here, I'd say:

1. No object state, "utility" methods: consider static methods and a
private constructor.

2. Requires object state: consider public constructor & instance variables.


OK, now I think I see what you are asking. "Should this class be made
"final"". My opinion: no. Never never make a class final unless you
have thought about it and are sure it must be final.

There's some extra design required when you DON'T make a class final,
but you should always go through that process. The reason is I think
called The Open-Closed Principle, and basically it means that you should
always leave open the possibility that someone will want to extend your
class. Try to let them if at all possible. Other principles aside
("Prefer composition to extension.") it's pernicious to actually prevent
extension unless you have a good reason. Imo.
From: markspace on
Rhino wrote:

> Again, can you clarify this a bit? You don't necessarily need to write
> an example; just pointing to a document or tutorial that contains an
> example would be just fine. I'm not sure where to look for such a
> thing.


A lot of what is being discussed here is based on patterns from a book
called "Effective Java" by Joshua Bloch. It's basically "design
patterns for Java" and it's very good. You should pick it up. Whether
you use its ideas or not is up to you, but I think it would extend your
understanding of Java quite a bit.


The basics of the Factory pattern are:

1. A static method that is the Factory.

2. A private-ish class that is produced by the Factory method.


public class StringUtils {

private StringUtils() {}

public StringUtils getInstance() {
return new StringUtils();
}
}


That's the idea, the full pattern can be more complicated. The
reasoning behind it is that there are some things you can't do in a
constructor, so the method gives you a change to add additional code
after (or before) the constructor is invoked. It's basically an
additional layer of encapsulation on top of the constructor. You should
look at the Java API and notice that a lot of the new-ish classes use
this kind of Factory pattern. Calendar, for example, and some of the
new Collections, like EnumSet.