Loading ...
Sorry, an error occurred while loading the content.

Monostates vs. Singletons (Was: Re: [XP] Singletons == Global s?)

Expand Messages
  • azami@speakeasy.net
    ... lot. ;-) ... Monty Python and the Holy Grail. And I believe the quote is, On second thought, let s not go to Camelot. Tis a silly place. -Matthew
    Message 1 of 27 , Apr 2, 2001
    • 0 Attachment
      --- In extremeprogramming@y..., Ryan King <rking@c...> wrote:
      > > "On second thought, let's not go to Camelot. They are a silly
      lot." ;-)
      > You're my next victim -- Where does that Camelot thing come from?

      Monty Python and the Holy Grail. And I believe the quote is, "On
      second thought, let's not go to Camelot. 'Tis a silly place."

      -Matthew
      azami@...
    • Dinwiddie, George
      Thanks, I haven t seen that movie lately and I m starting to forget a few lines. - George I saw a doctor, once. E didn t see me. I was iding. From:
      Message 2 of 27 , Apr 2, 2001
      • 0 Attachment
        Thanks, I haven't seen that movie lately and I'm starting to forget
        a few lines.

        - George

        "I saw a doctor, once. 'E didn't see me. I was 'iding."


        From: azami@... [mailto:azami@...]
        > --- In extremeprogramming@y..., Ryan King <rking@c...> wrote:
        > > > "On second thought, let's not go to Camelot. They are a silly
        > lot." ;-)
        > > You're my next victim -- Where does that Camelot thing come from?
        >
        > Monty Python and the Holy Grail. And I believe the quote is, "On
        > second thought, let's not go to Camelot. 'Tis a silly place."
      • Dinwiddie, George
        ... I don t think that getInstance implies a singleton or not. ... eh??? ... it ... OK, putting the log prefix each time isn t a great solution. (I ll blame
        Message 3 of 27 , Apr 2, 2001
        • 0 Attachment
          > From: Ryan King [mailto:rking@...]

          > Wwhat I was getting at was that the member "SomeSingleton::instance_"
          > seems to me to be a subpart of "class SomeSingleton".
          >
          > On the other hand, it is true that you could re-work the innards of "class
          > SomeSingleton" and "SomeSingleton::getInstance()" so that it can have
          > instance data, proving that the structure isn't known by the users of the
          > class.
          >
          > I have two problems with that solution, though:
          >
          > 1) Now the code is definitely lying. "getInstance()" means
          > "getTheInstance()", but we're redefining it to mean "getAnInstance()".
          > What does the operator "new" mean but "getAnInstance()"? Why not use
          > it instead, even if there is incidentally only one?

          I don't think that getInstance implies a singleton or not.

          > 2) On the practical side, it requires more thought and code to do the
          > necessary rewrite (as compared to a Monostate).

          eh???

          > > Well, I wouldn't think of putting such state into the Logger. I treat
          it
          > > as a facility that all the code can use, but none of them own it.
          >
          > I would at least think of it, because I the following is redundant:
          >
          > > String logPrefix = "foo: ";
          > > log(logPrefix, [...]
          > > log(logPrefix, [...]
          > > log(logPrefix, [...]
          >
          > The point here is: If you have an object that is a hybrid between class
          > data and instance data you will have a more difficult time if you're
          > starting with the Singleton pattern. I've always thought of static data
          > as smell, and it seems that the difficulty involved in creating instance
          > data discourages removal of this smell.

          OK, putting the log prefix each time isn't a great solution. (I'll blame
          it on my invisible pair.)

          How about this. Let's say I start with a singleton class like this:

          public class Logger {
          private static Logger singleton = new Logger();
          private Logger() {
          }
          public void log(String message) {
          System.out.println(message);
          }
          public static Logger getInstance() {
          return singleton;
          }
          }

          Now, we want to add prefixes:

          public class Logger {
          private static final String emptyString = "";
          private String prefix;
          private static Map loggers = new HashMap();
          private Logger(String prefix) {
          loggers.put(prefix, this);
          }
          public void log(String message) {
          System.out.println(prefix+message);
          }
          public static Logger getInstance() {
          return getInstance(emptyString);
          }
          public static Logger getInstance(String prefix) {
          Logger instance;
          if (loggers.containsKey(prefix)) {
          instance = (Logger)loggers.get(prefix);
          } else {
          instance = new Logger(prefix);
          }
          return instance;
          }
          }

          Does this smell better?

          - George

          P.S. Thanks for this discussion. Currently I don't have anyone suitable
          for
          discussing code smells. Too many people here haven't developed a nose or
          think
          that "if it ain't broke, don't fix it." I need the feedback.
        • Eric Bennett
          ... Color me clueless. Why not just add a method public static void Log(String message) { getInstance().log( message ); } and call it with Logger.Log(
          Message 4 of 27 , Apr 2, 2001
          • 0 Attachment
            On Mon, 2 Apr 2001, Dinwiddie, George wrote:

            > public class Logger {
            > private static Logger singleton = new Logger();
            > private Logger() {
            > }
            > public void log(String message) {
            > System.out.println(message);
            > }
            > public static Logger getInstance() {
            > return singleton;
            > }
            > }

            Color me clueless. Why not just add a method

            public static void Log(String message) {
            getInstance().log( message );
            }

            and call it with Logger.Log( "lalala" );

            The getInstance/log combo doesn't tell you anything more about what state
            the logger maintains or what the intent is of keeping an instance of it.

            I fail to see how code which does logging via Logger.getInstance().log()
            could remain unmodified if you added prefixes or other semantics to the
            logger. Since you will have to refactor client code anyway might as well
            choose the simplest, prettiest option - which to me is Logger.Log().

            - Eric B.

            --
            "Actually I'm a Lumberjack, and I'm okay!"
          • Dinwiddie, George
            Good point. I thought of that possibility, but then thought that I d be more likely to collapse them into a single class, as shown, at least until I needed to
            Message 5 of 27 , Apr 2, 2001
            • 0 Attachment
              Good point. I thought of that possibility, but then thought that
              I'd be more likely to collapse them into a single class, as shown,
              at least until I needed to differentiate them. To me, it was an
              easier refactoring.

              I notice that your PrefixedLogger is quite different from your
              Logger.
              - It doesn't use a factory to create it.
              - It's not a derived class, so there's more work to convert
              calling code from Logger to PrefixedLogger.

              Since we don't have any actual client code, maybe this is ok.
              It kinda nags at me, though.

              - George

              -----Original Message-----
              From: Rex_Jolliff@... [mailto:Rex_Jolliff@...]

              Your solution seems to be doing two things in one, how about:

              public class Logger {
              private static Logger singleton = new Logger();
              private Logger() {
              }
              public void log(String message) {
              System.out.println(message);
              }
              public static Logger getInstance() {
              return singleton;
              }
              }

              public class PrefixedLogger {
              String Prefix;

              public PrefixedLogger (String aPrefix) {
              this.Prefix = aPrefix;
              }
              public void log (String aMessage) {
              Logger.getInstance ().log (this.Prefix + aMessage);
              }
              }





              "Dinwiddie, George" <George.Dinwiddie@...> on 04/02/2001 11:21:35
              AM

              Please respond to extremeprogramming@yahoogroups.com











              To: "'extremeprogramming@yahoogroups.com'"
              <extremeprogramming@yahoogroups.com>

              cc: (bcc: Rex Jolliff/YM/RWDOE)



              Subject: RE: Monostates vs. Singletons (Was: Re: [XP]
              Singletons == Global s?)





              Federal Record Status Not
              Determined




              > From: Ryan King [mailto:rking@...]

              > Wwhat I was getting at was that the member "SomeSingleton::instance_"
              > seems to me to be a subpart of "class SomeSingleton".
              >
              > On the other hand, it is true that you could re-work the innards of "class
              > SomeSingleton" and "SomeSingleton::getInstance()" so that it can have
              > instance data, proving that the structure isn't known by the users of the
              > class.
              >
              > I have two problems with that solution, though:
              >
              > 1) Now the code is definitely lying. "getInstance()" means
              > "getTheInstance()", but we're redefining it to mean "getAnInstance()".
              > What does the operator "new" mean but "getAnInstance()"? Why not use
              > it instead, even if there is incidentally only one?

              I don't think that getInstance implies a singleton or not.

              > 2) On the practical side, it requires more thought and code to do the
              > necessary rewrite (as compared to a Monostate).

              eh???

              > > Well, I wouldn't think of putting such state into the Logger. I treat
              it
              > > as a facility that all the code can use, but none of them own it.
              >
              > I would at least think of it, because I the following is redundant:
              >
              > > String logPrefix = "foo: ";
              > > log(logPrefix, [...]
              > > log(logPrefix, [...]
              > > log(logPrefix, [...]
              >
              > The point here is: If you have an object that is a hybrid between class
              > data and instance data you will have a more difficult time if you're
              > starting with the Singleton pattern. I've always thought of static data
              > as smell, and it seems that the difficulty involved in creating instance
              > data discourages removal of this smell.

              OK, putting the log prefix each time isn't a great solution. (I'll blame
              it on my invisible pair.)

              How about this. Let's say I start with a singleton class like this:

              public class Logger {
              private static Logger singleton = new Logger();
              private Logger() {
              }
              public void log(String message) {
              System.out.println(message);
              }
              public static Logger getInstance() {
              return singleton;
              }
              }

              Now, we want to add prefixes:

              public class Logger {
              private static final String emptyString = "";
              private String prefix;
              private static Map loggers = new HashMap();
              private Logger(String prefix) {
              loggers.put(prefix, this);
              }
              public void log(String message) {
              System.out.println(prefix+message);
              }
              public static Logger getInstance() {
              return getInstance(emptyString);
              }
              public static Logger getInstance(String prefix) {
              Logger instance;
              if (loggers.containsKey(prefix)) {
              instance = (Logger)loggers.get(prefix);
              } else {
              instance = new Logger(prefix);
              }
              return instance;
              }
              }

              Does this smell better?

              - George

              P.S. Thanks for this discussion. Currently I don't have anyone suitable
              for
              discussing code smells. Too many people here haven't developed a nose or
              think
              that "if it ain't broke, don't fix it." I need the feedback.


              To Post a message, send it to: extremeprogramming@...

              To Unsubscribe, send a blank message to:
              extremeprogramming-unsubscribe@...

              Don't miss XP UNIVERSE, the first US conference on XP and Agile Methods.
              Early
              registration discounts until April 10, 2001. www.xpuniverse.com for details
              and
              registration.

              Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/






              To Post a message, send it to: extremeprogramming@...

              To Unsubscribe, send a blank message to:
              extremeprogramming-unsubscribe@...

              Don't miss XP UNIVERSE, the first US conference on XP and Agile Methods.
              Early registration discounts until April 10, 2001. www.xpuniverse.com for
              details and registration.

              Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
            • Dinwiddie, George
              As my example showed, you *don t* have to change the client code if they don t require a prefix. As for your suggestion, if you re going to go that route, why
              Message 6 of 27 , Apr 2, 2001
              • 0 Attachment
                As my example showed, you *don't* have to change the
                client code if they don't require a prefix.

                As for your suggestion, if you're going to go that
                route, why not just condense it to

                public class Logger {
                public static void Log(String message) {
                System.out.println(message);
                }
                }

                In fact, the above is frequently my starting point in a program.
                It usually doesn't last very long, though, before I rip it out
                and replace it with something else. Maybe that's just prejudice
                on my part, however.

                Does a static method have more or less smell than a singleton
                accessed via a static factory method?

                - George

                -----Original Message-----
                From: Eric Bennett [mailto:ericb@...]

                On Mon, 2 Apr 2001, Dinwiddie, George wrote:

                > public class Logger {
                > private static Logger singleton = new Logger();
                > private Logger() {
                > }
                > public void log(String message) {
                > System.out.println(message);
                > }
                > public static Logger getInstance() {
                > return singleton;
                > }
                > }

                Color me clueless. Why not just add a method

                public static void Log(String message) {
                getInstance().log( message );
                }

                and call it with Logger.Log( "lalala" );

                The getInstance/log combo doesn't tell you anything more about what state
                the logger maintains or what the intent is of keeping an instance of it.

                I fail to see how code which does logging via Logger.getInstance().log()
                could remain unmodified if you added prefixes or other semantics to the
                logger. Since you will have to refactor client code anyway might as well
                choose the simplest, prettiest option - which to me is Logger.Log().

                - Eric B.
              • azami@speakeasy.net
                ... blame ... Better, but still not very good. In my opinion. Maybe I d like it better if some of the names were changed - getInstance() by convention
                Message 7 of 27 , Apr 2, 2001
                • 0 Attachment
                  --- In extremeprogramming@y..., "Dinwiddie, George"
                  <George.Dinwiddie@a...> wrote:
                  > > From: Ryan King [mailto:rking@c...]
                  > > I would at least think of it, because I the following is
                  redundant:
                  > >
                  > > > String logPrefix = "foo: ";
                  > > > log(logPrefix, [...]
                  > > > log(logPrefix, [...]
                  > > > log(logPrefix, [...]
                  >
                  > OK, putting the log prefix each time isn't a great solution. (I'll
                  blame
                  > it on my invisible pair.)
                  >
                  > How about this. Let's say I start with a singleton class like this:
                  > ...
                  > Now, we want to add prefixes:
                  >
                  > public class Logger {
                  > private static final String emptyString = "";
                  > private String prefix;
                  > private static Map loggers = new HashMap();
                  > private Logger(String prefix) {
                  > loggers.put(prefix, this);
                  > }
                  > public void log(String message) {
                  > System.out.println(prefix+message);
                  > }
                  > public static Logger getInstance() {
                  > return getInstance(emptyString);
                  > }
                  > public static Logger getInstance(String prefix) {
                  > Logger instance;
                  > if (loggers.containsKey(prefix)) {
                  > instance = (Logger)loggers.get(prefix);
                  > } else {
                  > instance = new Logger(prefix);
                  > }
                  > return instance;
                  > }
                  > }
                  >
                  > Does this smell better?

                  Better, but still not very good. In my opinion. Maybe I'd like it
                  better if some of the names were changed - getInstance() by convention
                  implies singleton. This is only by convention, it doesn't enforce it
                  in code or anything, and I'd always write code not to care whether the
                  result of getInstance() is a singleton or not. Also, you'll end up
                  with (potentially) different log object instances all trying to
                  operate on the same resource, which could get tricky in a
                  multi-threaded application. Not unsolvable, just unnecessary. :-)

                  My idea: Write the logger as a singleton. Write an access class for
                  the logger (could use the same interface) that is not a singleton and
                  has state (the prefix).

                  class PrefixedLogger {
                  private String prefix;
                  public String getPrefix() { return prefix; }
                  public setPrefix(String prefix) { this.prefix = prefix; }

                  public log(String message) {
                  Logger.Log(prefix + ": " + message); //See NOTE below
                  }
                  }

                  NOTE: I prefer in some cases to avoid the indirection of
                  getInstance(), and use static methods instead. It's more work if/when
                  you need more than one instance, but in the meantime the syntax is
                  simple and intuitive - just like System.out. If you want proof that
                  this is simpler, just watch how typical beginning Java programmers
                  react to all the getInstance() and toolbox stuff!

                  Reactions?

                  -Matthew
                  azami@...
                • Eric Hodges
                  ... PrefixedLogger is fundamentally different from Logger, though. Logger is a Singleton. PrefixedLogger isn t. (I suggested this solution a week or 2 ago,
                  Message 8 of 27 , Apr 2, 2001
                  • 0 Attachment
                    > -----Original Message-----
                    > From: Dinwiddie, George [mailto:George.Dinwiddie@...]
                    > Sent: Monday, April 02, 2001 2:40 PM
                    > To: 'extremeprogramming@yahoogroups.com'
                    > Subject: RE: Monostates vs. Singletons (Was: Re: [XP] Singletons ==
                    > Global s?)
                    >
                    >
                    > Good point. I thought of that possibility, but then thought that
                    > I'd be more likely to collapse them into a single class, as shown,
                    > at least until I needed to differentiate them. To me, it was an
                    > easier refactoring.
                    >
                    > I notice that your PrefixedLogger is quite different from your
                    > Logger.
                    > - It doesn't use a factory to create it.
                    > - It's not a derived class, so there's more work to convert
                    > calling code from Logger to PrefixedLogger.

                    PrefixedLogger is fundamentally different from Logger, though. Logger is a
                    Singleton. PrefixedLogger isn't.

                    (I suggested this solution a week or 2 ago, btw.)
                  • Eric Bennett
                    ... Oh, agreed. I would start with this about 10 seconds before I made System.out a variable so a new stream could be swapped in for testing. ... Less in my
                    Message 9 of 27 , Apr 2, 2001
                    • 0 Attachment
                      On Mon, 2 Apr 2001, Dinwiddie, George wrote:

                      > As for your suggestion, if you're going to go that
                      > route, why not just condense it to
                      >
                      > public class Logger {
                      > public static void Log(String message) {
                      > System.out.println(message);
                      > }
                      > }
                      >
                      > In fact, the above is frequently my starting point in a program.

                      Oh, agreed. I would start with this about 10 seconds before I made
                      "System.out" a variable so a new stream could be swapped in for testing.


                      > Does a static method have more or less smell than a singleton
                      > accessed via a static factory method?

                      Less in my book unless something non-global characterizes the factory.
                      Maybe I just don't get it yet.


                      - Eric B.

                      --
                      "LogFlume.add( new Log().add_rider( (FoolishLogger) this ) )"
                    • Dinwiddie, George
                      From: azami@speakeasy.net [mailto:azami@speakeasy.net] ... Well, my experience with the Java run-time-library doesn t suggest that getInstance() implies
                      Message 10 of 27 , Apr 2, 2001
                      • 0 Attachment
                        From: azami@... [mailto:azami@...]
                        > [snip]Maybe I'd like it
                        > better if some of the names were changed - getInstance() by convention
                        > implies singleton. This is only by convention, it doesn't enforce it
                        > in code or anything, and I'd always write code not to care whether the
                        > result of getInstance() is a singleton or not.

                        Well, my experience with the Java run-time-library doesn't suggest that
                        getInstance() implies singleton. Check out the various flavors of
                        java.util.Calendar.getInstance, for example. Maybe I'm wrong, but I've
                        standardized my code to use getInstance() for almost any factory
                        method. When I first coded singletons in Java, I used getSingleton(),
                        but quickly decided that my client code didn't care whether or not it
                        was a singleton. (I think this was about when I first converted a
                        singleton to a non-singleton.)

                        > Also, you'll end up
                        > with (potentially) different log object instances all trying to
                        > operate on the same resource, which could get tricky in a
                        > multi-threaded application. Not unsolvable, just unnecessary. :-)

                        Not so tricky. It's easy to put synchronization inside the Logger
                        class to make it thread safe.

                        > My idea: Write the logger as a singleton. Write an access class for
                        > the logger (could use the same interface) that is not a singleton and
                        > has state (the prefix).
                        [code snipped]
                        > NOTE: I prefer in some cases to avoid the indirection of
                        > getInstance(), and use static methods instead. It's more work if/when
                        > you need more than one instance, but in the meantime the syntax is
                        > simple and intuitive - just like System.out. If you want proof that
                        > this is simpler, just watch how typical beginning Java programmers
                        > react to all the getInstance() and toolbox stuff!

                        Yes, using a static method works. For some reason I tend not to use
                        that much any more. Somehow that seems more like a global, to me.

                        In any event, I wouldn't judge which is simpler by the reaction of a
                        novice programmer. I've seen too many that think sprinkling magic
                        numbers around the program is simpler.

                        So, among the options are:
                        1. using a static method, which implies a global, singleton service,
                        if not object.
                        2. using a constructor (which perhaps just initializes a Monostate),
                        which implies client control over the creation of objects.
                        3. using a factory method, which implies to me that the client has
                        no knowledge over whether a new object is being created or one is
                        being pulled out of a pool (that may only have one element). To others,
                        such as yourself, this seems to imply a singleton.

                        Except for the amount of typing, I currently think that #3 is just as
                        simple and is more general than #1 or #2. I don't use #3 exclusively,
                        however, and I'm willing to consider arguments for the alternatives.

                        - George
                      • Dinwiddie, George
                        From: Eric Hodges [mailto:eric.hodges@mongoosetech.com] ... a ... Does the client care whether it s a singleton, or not? To me, it s not that the client has a
                        Message 11 of 27 , Apr 2, 2001
                        • 0 Attachment
                          From: Eric Hodges [mailto:eric.hodges@...]
                          > PrefixedLogger is fundamentally different from Logger, though. Logger is
                          a
                          > Singleton. PrefixedLogger isn't.

                          Does the client care whether it's a singleton, or not? To me, it's not that
                          the client has a desire to do particular types of logging; it's that the
                          client has a responsibility to the application to log significant
                          occurrences.

                          In fact, I don't think I'd ever want the clients of an class to know
                          whether or not it's a singleton. It's not their business. If they
                          start making assumptions about that, you might as well use a global.
                          At least, that's my thinking.

                          So, I don't think that singleton-or-not makes a fundamental difference. I
                          think that's an implementation issue that should live inside the class. In
                          fact, if we're going to start having different flavors of Logger, I think
                          I'd be tempted to refactor Logger into an interface. I might also remove
                          the factory method from any class and create a LoggerFactory, instead.

                          In any event, I think I'm going to end up with a singleton root logging
                          object, because I want a single point of control for the logging output.
                          I'll also generally want to merger multiple log streams into one. Perhaps
                          I'll want to have multiple log streams, but I wouldn't want that to be
                          under the control of the client code that sends the log messages.

                          - George
                        • Eric Hodges
                          ... PrefixedLogger *should* be quite different from Logger. PrefixedLogger isn t a Singleton, so it shouldn t be a subclass of a Singleton. PrefixedLogger
                          Message 12 of 27 , Apr 2, 2001
                          • 0 Attachment
                            > -----Original Message-----
                            > From: Dinwiddie, George [mailto:George.Dinwiddie@...]
                            > Sent: Monday, April 02, 2001 3:36 PM
                            > To: 'extremeprogramming@yahoogroups.com'
                            > Subject: RE: Monostates vs. Singletons (Was: Re: [XP] Singletons ==
                            > Global s?)
                            >
                            >
                            > From: Eric Hodges [mailto:eric.hodges@...]
                            > > PrefixedLogger is fundamentally different from Logger, though.
                            > Logger is
                            > a
                            > > Singleton. PrefixedLogger isn't.
                            >
                            > Does the client care whether it's a singleton, or not? To me,
                            > it's not that
                            > the client has a desire to do particular types of logging; it's that the
                            > client has a responsibility to the application to log significant
                            > occurrences.

                            The client doesn't care. I was responding to this:

                            > I notice that your PrefixedLogger is quite different from your
                            > Logger.
                            > - It doesn't use a factory to create it.
                            > - It's not a derived class, so there's more work to convert
                            > calling code from Logger to PrefixedLogger.

                            PrefixedLogger *should* be quite different from Logger. PrefixedLogger
                            isn't a Singleton, so it shouldn't be a subclass of a Singleton.
                            PrefixedLogger doesn't need a factory method, it can use "new".

                            >
                            > In fact, I don't think I'd ever want the clients of an class to know
                            > whether or not it's a singleton. It's not their business. If they
                            > start making assumptions about that, you might as well use a global.
                            > At least, that's my thinking.
                            >
                            > So, I don't think that singleton-or-not makes a fundamental difference. I
                            > think that's an implementation issue that should live inside the
                            > class. In
                            > fact, if we're going to start having different flavors of Logger, I think
                            > I'd be tempted to refactor Logger into an interface. I might also remove
                            > the factory method from any class and create a LoggerFactory, instead.

                            You shouldn't try to make a non-Singleton subclass of a Singleton. If that
                            means the clients treat Logger differently from PrefixedLogger, so be it.
                          • azami@speakeasy.net
                            ... convention ... it ... the ... that ... I ve ... My brain wasn t fully in gear before I engaged my fingers. You ve expressed my true thoughts far better
                            Message 13 of 27 , Apr 2, 2001
                            • 0 Attachment
                              --- In extremeprogramming@y..., "Dinwiddie, George"
                              <George.Dinwiddie@a...> wrote:
                              >
                              > From: azami@s... [mailto:azami@s...]
                              > > [snip]Maybe I'd like it
                              > > better if some of the names were changed - getInstance() by
                              convention
                              > > implies singleton. This is only by convention, it doesn't enforce
                              it
                              > > in code or anything, and I'd always write code not to care whether
                              the
                              > > result of getInstance() is a singleton or not.
                              >
                              > Well, my experience with the Java run-time-library doesn't suggest
                              that
                              > getInstance() implies singleton. Check out the various flavors of
                              > java.util.Calendar.getInstance, for example. Maybe I'm wrong, but
                              I've
                              > standardized my code to use getInstance() for almost any factory

                              My brain wasn't fully in gear before I engaged my fingers. You've
                              expressed my true thoughts far better than I did. In fact,
                              getInstance() implies factory to me, and factory implies more than one
                              instance. After all, if there's only one of a thing what the heck do
                              you need a factory for? Just use the thing.

                              > method. When I first coded singletons in Java, I used
                              getSingleton(),
                              > but quickly decided that my client code didn't care whether or not
                              it
                              > was a singleton. (I think this was about when I first converted a
                              > singleton to a non-singleton.)

                              Ideally, the client code should not know whether the object is a
                              singleton. You could argue that Logger.Log() looks more like a
                              singleton than Logger.getInstance().Log(), but

                              1 - you _can_ introduce instances without changing that interface if
                              you need to
                              2 - I think the result is simpler, and until you need more complexity
                              it's worth it.

                              > > Also, you'll end up
                              > > with (potentially) different log object instances all trying to
                              > > operate on the same resource, which could get tricky in a
                              > > multi-threaded application. Not unsolvable, just unnecessary. :-)
                              >
                              > Not so tricky. It's easy to put synchronization inside the Logger
                              > class to make it thread safe.

                              You need class-level synchronization. The most intuitive ways of
                              synchronizing synchronize on instances. So, two instances could try
                              to simultaneously access the same resource. You have to remember to
                              protect the resource, not the Logger objects. But since the Logger is
                              conceptually representative of the resource, this will be easily
                              missed...

                              > Yes, using a static method works. For some reason I tend not to use
                              > that much any more. Somehow that seems more like a global, to me.

                              I think the concept of a "global service" is good for services that
                              are global. It is vitally important that (from the client's
                              perspective) the service is stateless. One object's use of a global
                              service must not impact any other object's use of the service.

                              For this reason I think it's important to conceptually separate
                              methods for using the service from methods for configuring the
                              service.

                              E.g., it's safe to use System.out wherever you want, but using
                              System.SetOut() is rather heinous if not carefully controlled.

                              > In any event, I wouldn't judge which is simpler by the reaction of a
                              > novice programmer. I've seen too many that think sprinkling magic
                              > numbers around the program is simpler.

                              A Java beginner isn't necessarily a novice programmer. Anytime a
                              programmer says in frustration, "Why won't it just let me X?!" or "I
                              can't believe I need to do X, Y, and Z just to accomplish Q!", there's
                              a big red flag about complexity. People experienced in a language are
                              used to its unnecessary complexities and tend to overlook them easily.

                              > So, among the options are:
                              > 1. using a static method, which implies a global, singleton
                              service,
                              > if not object.

                              I like this until something more is needed. As I mentioned, a global
                              service does not strike me as a bad thing when you're providing a
                              service that is global.

                              > 2. using a constructor (which perhaps just initializes a
                              Monostate),
                              > which implies client control over the creation of objects.

                              This seems like a clever trick to avoid having to change a lot of
                              client code during a refactoring when you actually do need different
                              instances all over the place. IMHO, YAGNI.

                              > 3. using a factory method, which implies to me that the client has
                              > no knowledge over whether a new object is being created or one is
                              > being pulled out of a pool (that may only have one element). To
                              others,
                              > such as yourself, this seems to imply a singleton.

                              As I mentioned, kind of a brain fart. Factory implies things are
                              being made. What factory really says to me is that I'm giving up
                              control of construction so that the factory can create a class I don't
                              know about (or shouldn't care about or don't know enough to choose) -
                              like a subclass of the class I asked for, or an implementer of the
                              interface I asked for. Factories have to do with abstraction, not
                              singleton-ness.

                              > Except for the amount of typing, I currently think that #3 is just
                              as
                              > simple and is more general than #1 or #2. I don't use #3
                              exclusively,
                              > however, and I'm willing to consider arguments for the alternatives.

                              I prefer #1 for global services, and #3 for hiding a variety of
                              implementations/subclasse so that client code doesn't need to know
                              when new implementations/subclasses are added. These are very
                              different uses. I would only ever use #2 if the client code
                              conceptually wanted control over object creation and instances. I
                              can't really think of a case where the client wants to believe it has
                              its own instance but there's no actual need for different instances,
                              except maybe as a step during a refactoring between a singleton and
                              multipletons (in either direction).

                              Best,
                              Matthew
                              azami@...
                            Your message has been successfully submitted and would be delivered to recipients shortly.