Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / May 2005

Tip: Looking for answers? Try searching our database.

static or not?

Thread view: 
David Vanderschel - 20 May 2005 00:02 GMT
There are many situations when one has a Class for
which it only makes sense that a single instance be
created in a given session.  It seems to me that, in
this situation, it does not really make much
difference whether the Class's variables are declared
as static or not.  There is still only going to be one
instance of each anyway.  I have determined by
experiment that such a program compiles and works the
same either way.  (I have encountered a couple
situations where the compiler was not happy until I
made a certain variable static because I had
referenced it from a static context.  But such
situations are rare for me.)

My question:  When you have the choice, which choice
should you make?  My guess is that static declarations
may lead to more efficient code; but I have been
unable to find any discussion of this issue.  (Part of
the problem here is that Sun's search on "static" hits
just about everything.  Its concept of relevance seems
pretty weak.)  If it makes no difference, then I see
no point in cluttering the code with unnecessary
"static" key words.

I could use some guidance on this issue.

Any pointers appreciated,
 David V.
iamfractal@hotmail.com - 20 May 2005 08:37 GMT
> There are many situations when one has a Class for
> which it only makes sense that a single instance be
[quoted text clipped - 24 lines]
> Any pointers appreciated,
>   David V.

Hi, David,

When I need a single instance, I use a singleton (with a non-private
constructor, admittedly), with a static getInstance() method and all
other methods and data non-static.

I have no idea whether static data/methods lead to more efficient code,
but I think if your application depends upon such efficiency gains then
perhaps a non-interpreted language is better suited to your needs.

The minor reason I use as many non-static data/methods as possible is
because it makes it slightly easier to subclass the class if I find
that I was wrong in my  assumption of the class's singularness, and
that perhaps two specific variants of the class are more suitable. If
it were a significant effort to use a singleton over using all static
data/methods, then I wouldn't bother; but singletons are, I find, easy
to design and use.

The major reason I use a singleton applies only when the singleton is
declared as public, i.e., is accessible outside its package.
Dependencies on concrete classes outside their home packages are more
dangerous than dependencies on concrete classes within their home
packages, as packages should be as encapsulated at possible/convenient.
So I prefer to cite the first principle of OO ("Program to an interface
not an implementation") when dealing with public classes, and try to
access the services they offer via an interface (or an abstract class)
rather than by the concrete class itself. Thus, I can alter the
implementation of the concrete class without affecting its clients.

I generally do this by having the singleton register itself in a public
Registry class. Yes, this is a concrete class visible to all packages,
but I keep this class as simple as possible: it only stores and returns
interface, and particluarly has no dependencies on the methods
contained in those interfaces, so I can change the the entire set of
methods within any given interface without changing the Registry code.

If I use a singleton, then I can strip away an interface from this
singleton, and have it register that interface in the Registry.

If I use static methods, I cannot do this: static methods are not
allowed to hide the instance methods of the interface.

This is the major reason I use a singleton, instead of a class of
static methods.

.ed

www.EdmundKirwan.com - Home of The Fractal Class Composition.
hawat.thufir@gmail.com - 24 May 2005 04:20 GMT
...
> If I use a singleton, then I can strip away an interface from this
> singleton, and have it register that interface in the Registry.
[quoted text clipped - 4 lines]
> This is the major reason I use a singleton, instead of a class of
> static methods.
...

would expand on your thoughts here?  instead of having, for example, a
"driver" class you'd have a singleton?

thanks,

Thufir
iamfractal@hotmail.com - 25 May 2005 08:56 GMT
Hi, Thufir,

Well, I'm not sure what you mean by a, "Driver," class, so I'll take a
guess a guess at a definition: a Driver class is a class that
coordinates a sequence of interactions with a number of other classes.

(If that's not what you meant, of course, then the rest of this post
is irrelevant.)

I did not mean to imply that I would automatically make any such
Driver class a singleton. Several instances of such a class may be
required, in which case my reply to the OP does not hold.

If the application did, however, require one and only one Driver
object to be instantiated, then I would have a small preference to
using a singleton as opposed to a class of static methods, if this
Driver was not accessible outside its package.

On a system-level, the package is generally the primary unit of
encapsulation, as opposed to the class (though of course even
class-level behaviour should be as encapsulated as possible);
afterall, if you were presented with a presentation on a new system,
would you rather be first presented with a web of 5,000 classes, or 40
packages?

Such being the case, the main reason for this small preference for a
singleton would be the possibility that the Driver might, some day, be
made accessible outside its package. While Driver is only visible
inside one package, then having all the classes depend on the Driver's
concrete class is not too big a problem, because the reason all these
classes are packaged together is (presumably) that they have some
commonality of purpose, for example, they all work to put a GUI on a
screen. Thus it's possible that if there are new requirements on the
GUI, the implementation of many classes within that package might be
impacted, and the degree to which they can all be hidden from one
another is limited.

If, however, the day comes that the Driver must be accessible outside
the
package, then there will suddenly be a strong preference for having
Driver implemented as a singleton rather than a class of static
methods.

If we continue with out example, the Driver that controls the
display of the GUI is now being depended on by another package which
(presumably) has nothing to do with GUI: it could, for example, be a
Database class that wants to output a query result, but doesn't care
whether
the output is made to a GUI, a socket, a text file, etc.

If Driver were a class of static methods, then Databse would now need
a dependency on the concrete class Driver. And as Driver only controls
the GUI, then if Database wants to output to a text file, it must have
some knowledge of other functionality that writes its output to that
medium.

If Driver were a singleton, however, then, as mentioned, it could
declare an interface (View) that is registered in a Registry that is
known to Database. But all the other means of outputting data could
also register that same interface to implement functionality for their
own, specific medium. Thus TextView, FileView, and SocketView
could all register their View interface in the Registry.

And when Database wants to write a result, it can ask Registry to
return the currently-selected output medium implementation, hidden
behind the View interface. This current selection could be controlled
by a user option. Also, if there are new requirements on the GUI, such
as the requirement that output should be made via Email to the CEO,
this new view can be introduced to the system(e.g., EmailView) without
impacting the Database functionality.

Now, I'm just waiting to see, "No, that's not what I meant by Driver
..."

.ed

www.EdmundKirwan.com - Home of The Fractal Class Composition.
hawat.thufir@gmail.com - 26 May 2005 10:39 GMT
> Hi, Thufir,
...

> If Driver were a class of static methods, then Databse would now need
> a dependency on the concrete class Driver. And as Driver only controls
> the GUI, then if Database wants to output to a text file, it must have
> some knowledge of other functionality that writes its output to that
> medium.

right, follow you there.

> If Driver were a singleton, however, then, as mentioned, it could
> declare an interface (View) that is registered in a Registry that is
> known to Database. But all the other means of outputting data could
> also register that same interface to implement functionality for their
> own, specific medium. Thus TextView, FileView, and SocketView
> could all register their View interface in the Registry.
...

There'd be package "driverAndViews," or something, with the various
view interfaces package private; or, the views would be nested
within Driver.  The view interfaces are registered in Registry to
enable Database to send that e-mail to the CEO.

How does the communication between Database and Registry work?

> Now, I'm just waiting to see, "No, that's not what I meant by Driver
...

heh, not at all, spot on :)

-Thufir
iamfractal@hotmail.com - 26 May 2005 16:09 GMT
> > Hi, Thufir,
> ...
[quoted text clipped - 5 lines]
>
> How does the communication between Database and Registry work?

Hi, Thufir!

OK, lets aim this baby in the Model-View-Controller direction, and
kill half a flock of birds with one stone.

In the previous email, I mistakenly showed Driver as implementing a
View interface, but I will correct this in this example, and portray
Driver as a Controller. Do forgive this changed point of view, but it
should make the example more, "Real world."

It should forever strike you as odd when you hear a designer say,
"I've used the MVC pattern to organise my classes for this problem,"
and then when you see the design there's no model package, no view
package, and no controller package. A mistake we won't make as we
embellish this example.

The first principle of OO states, as you know, "Program to an
interface, not an implementation."

The theory we're discussing here can also be reduced to a shockingly
similar principle, "Program to an interface repository, not an
implementation repository."

We will hereby define an interface repository as a package containing
at most one concrete class. An implementation repository is a package
containing more than one concrete class.

Note that this theory was developed for industrial-sized systems, so
looks overkill here, but it should get the point across.

We will split this example application into five packages: model,
view, controller, start, and ir1. "ir1" is the standard name for the
first
interface repository. All these packages are usually peers (i.e., they
have the same parent package). model, view, and controller will all be
implementation repositories.

The start package is special: it contains just one class, Start, which
holds the public static void main() method, and is responsible for
triggering one public class in each of the three other implementation
repositories. So, in the model package, there will be one public
concrete class called, "ModelStart;" in the controller package, there
will be, "ControllerStart," etc. Crucially, these XStart classes are
the only public concrete classes in the implementation repositories;
all other classes in the package will be package-private. These XStart
classes then tell as many as necessary of the other, package-private
contrete classes in the implementation repositories that the system has
started, and they must register themselves in the registry.

The ir1 package will contain the singleton, concrete class Registry,
and will also contain the View interface. (In fact, ir1 will contain
*all* the interfaces visibile to all other packages; all the
interfaces - as well as the Registry class - in ir1 will be public.)

The model package will contain, as well as ModelStart, the concrete,
package-private class Database, which will implement the interface
ir1.Model.

The view package will contain, as well as ViewStart, the
package-private, concrete classes TextView, FileView, and SocketView,
all of which will implement ir1.View.

The controller package will contain, as well as public class
ControllerStart, the package-private concrete class Driver, which will
implement ir1.Controller.

When the start.Start class's main() method is called, it will, as
mentioned, contact all the other XStart classes, and they will order
the relevant package-private implementation classes to register in the
Registry. (Of course, in reality, only a few classes will need to
register.)

Thus, for example, controller.Driver will register its Controller
interface
in the Registry by calling:
Registry.getInstance().register(this).

Next, a user will make some input; we needn't specify how, here, but
suffice it to say that when that input is made, an object will need to
get that input into the system. It will do this by doing something
like:
Controller controller = Registry.getRegistry().getController();
controller.process(input);

The Driver object will have its process() method called, and will kick
the database into life, by something like:
Registry registry = Registry.getInstance();
Model model = registry.getModel();
model.doThis();
model.doThat();
Result result = model.getResult();

(OK, here's an interface I'd forgotten; any guesses where we'd declare
it?)

The Driver object would then output the result to the use by:
int viewID = registry.getCurrentViewID();
View view = registry.getView(viewID);
view.show(result);

Thus we have a system in which there are only two types of
inter-package, concrete class dependencies:

1) From Start to XStart - and these XStart classes only contain enough
  logic to kick start the business logic, in other words, these
  dependencies do not change as business logic changes.

2) Dependencies on the Registry concrete class - but this class simply
  stores and erturns interfaces, and has no dependencies on the
  methods of those interfaces, and thus is immune to changes of the
  interface methods (although of course will change as whole
  interfaces change, and new ones are added).

And *all* other inter-package dependencies are on interfaces
only. Thus, you can switch in any database you like, as long as it
conforms to the Model interface (this will, in reality, probably be
JDBC, or a wrapper thereof). The same goes for the Views and even the
Controller itself.

Hence, "Program to an interface repository, not an implementation
repository."

Note that model package, view package, and controller packages do not
depend on one another (you can Google for the heated discussions on
which of these packages should depend on one another, and which must
not), and that the system is guaranteed to be free from inter-package
circular dependencies.

Of course a full system will have hundreds of packages, and there will
be hierarchical start/implementation repository/irX packages, but the
design is - and particularly the benefits listed above are -
wonderfully extensible.

.ed

www.EdmundKirwan.com - Home of The Fractal Class Composition.
hawat.thufir@gmail.com - 27 May 2005 14:18 GMT
Hi, Ed!

...
> Thus, for example, controller.Driver will register its Controller
> interface in the Registry by calling:
> Registry.getInstance().register(this).

package controller;
package-private class Driver extends controller.Controller{
       void register() {
               Registry.getInstance().register(this);
       }
}
is the register method correct as far as it goes?

"If I use a singleton, then I can strip away an interface from this
singleton, and have it register that interface in the Registry.

If I use static methods, I cannot do this: static methods are not
allowed to hide the instance methods of the interface.

This is the major reason I use a singleton, instead of a class of
static methods. "  -Ed

this is where you're stripping away an interface?

> Next, a user will make some input; we needn't specify how, here, but
> suffice it to say that when that input is made, an object will need to
> get that input into the system. It will do this by doing something
> like:
> Controller controller = Registry.getRegistry().getController();
> controller.process(input);

if this is done from class foo, what's foo's package? of MVC
I think view, but view presents data to the user, so I'm not sure.

> The Driver object will have its process() method called, and will kick
> the database into life, by something like:
[quoted text clipped - 6 lines]
> (OK, here's an interface I'd forgotten; any guesses where we'd declare
> it?)

heh, ir1 of course.

> The Driver object would then output the result to the use by:
> int viewID = registry.getCurrentViewID();
> View view = registry.getView(viewID);
> view.show(result);

where did result come from, please?
view.show() might trigger a SQL query and would show the outcome of
that query?

you said "...portray Driver as a Controller," so it's:

package controller;
package-private class Driver implements SomeInterface {...

> Thus we have a system in which there are only two types of
> inter-package, concrete class dependencies:
>
> 1) From Start to XStart - and these XStart classes only contain enough
>    logic to kick start the business logic, in other words, these
>    dependencies do not change as business logic changes.

if everything in the start package is business logic, might that
logic consist of static methods, like Math.sin(x), or is that a bit
extreme?

> 2) Dependencies on the Registry concrete class - but this class simply
>    stores and erturns interfaces, and has no dependencies on the
>    methods of those interfaces, and thus is immune to changes of the
>    interface methods (although of course will change as whole
>    interfaces change, and new ones are added).

> And *all* other inter-package dependencies are on interfaces
> only. Thus, you can switch in any database you like, as long as it
[quoted text clipped - 10 lines]
> not), and that the system is guaranteed to be free from inter-package
> circular dependencies.

err, next time ;)

> Of course a full system will have hundreds of packages, and there will
> be hierarchical start/implementation repository/irX packages, but the
[quoted text clipped - 4 lines]
>
> www.EdmundKirwan.com - Home of The Fractal Class Composition.

this helps to justify MVC for me, thanks.

-Thufir
hawat.thufir@gmail.com - 27 May 2005 14:27 GMT
> Hi, Ed!
>
[quoted text clipped - 9 lines]
>         }
> }
...

err,

package controller;
package-private class Driver implements ir1.Controller{
        void register() {
                Registry.getInstance().register(this);
        }
}
iamfractal@hotmail.com - 31 May 2005 16:17 GMT
> Hi, Ed!
>
[quoted text clipped - 21 lines]
>
> this is where you're stripping away an interface?

Exactly, though I should have pointed out the signature of this method,
as it is crucial. This method will have signature:

void register(Controller controller);

And not,
void register(Driver controller);

This any Driver implementation could register, as long as it implements
the Controller interface. This would not be possible if we tried to
register a class of static methods.

> > Next, a user will make some input; we needn't specify how, here, but
> > suffice it to say that when that input is made, an object will need to
[quoted text clipped - 5 lines]
> if this is done from class foo, what's foo's package? of MVC
> I think view, but view presents data to the user, so I'm not sure.

Well, class Foo, in this case, will be a class that captures user
input, which is traditionally put in the controller package. As the
user input could be from a button click (if the tool is started
graphically) or from a class just reading command line input, these
classes - specific to user input - are usually put in a subpackage of
controller.

For example, controller.gui would hold the GUI widgets waiting for
button clicks, and controller.cli would have classes reading from the
command line.

In our small example, however, it would be perfectly acceptable to have
all these user-input classes lumped into the controller package itself.

> > The Driver object will have its process() method called, and will kick
> > the database into life, by something like:
[quoted text clipped - 8 lines]
>
> heh, ir1 of course.

Absolutely!

> > The Driver object would then output the result to the use by:
> > int viewID = registry.getCurrentViewID();
[quoted text clipped - 4 lines]
> view.show() might trigger a SQL query and would show the outcome of
> that query?

This is a continuation of the code written above; result is just a
convenient way to pass view-independent data from controller to the
view. The Driver code altogether will be:

Registry registry = Registry.getInstance();
Model model = registry.getModel();
model.doThis();
model.doThat();
Result result = model.getResult();
int viewID = registry.getCurrentViewID();
View view = registry.getView(viewID);
view.show(result);

Here we see, again, that Driver has only one dependency one a concrete
class, and all the rest are interfaces.

> you said "...portray Driver as a Controller," so it's:
>
> package controller;
> package-private class Driver implements SomeInterface {...

Correct, and that SomeInterface will actuall be the Controller
interface.

> > Thus we have a system in which there are only two types of
> > inter-package, concrete class dependencies:
[quoted text clipped - 6 lines]
> logic consist of static methods, like Math.sin(x), or is that a bit
> extreme?

I didn't phrase this well. I meant to say that everything in the start
package is NOT dependent on business logic: all the start package knows
is how to call a single method (usually start()) on one concrete class
in some other subsystems. Admittedly, this method could of course be
static, but I still use singletons for these (yes, the getInstance() is
static in fact).

So our start package will contain on class which will look something
like this:

class Start {
  public static void main(String[] args} (
     ModelStart.getInstance().start();
     ControllerStart.getInstance().start();
     ViewStart.getInstance().start();
  )
}

And thus all the subsystems get a change to register relevant objects
in the registry before the user starts clicking things.

Note, in the real world, the start phase is usually more complicated,
using either broadcasts of sequentially increasing phases (so that, for
example, the Registry object starts in phase 1, the ConcreteModel
registers in phase 2, Driver registers in phase 3, etc.) or Observers
all register to be notified of registrations together, and a first
registration triggers a wave of registering throughout the system.

> > 2) Dependencies on the Registry concrete class - but this class simply
> >    stores and erturns interfaces, and has no dependencies on the
[quoted text clipped - 31 lines]
>
> -Thufir


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.