Weird behavior on allocation...what's going on?

Z

Zerex71

Lew said:
Don't have instance variables for x, y and z. Define the methods in terms of
the underlying, inherited array.
public double x()
{
return array [0] [0];
}
Zerex71 said:
Your last suggestion I can live with. I just wanted to use the x, y,
and z names as ways to reference.
That still leaves the question of how the array gets updated if I am
using the class in a static fashion
i.e. not setting its individual members to particular values.

Use an appropriate setBlah( double val ) method.

Or perhaps setBlah( double val, int row, int col ).

This business of hiding all attributes behind accessor methods is quite
powerful, at the cost of verbosity. A method pair "setX()" and "getX()" need
never reference an actual instance variable "x" within the black box. They
only need to present to API clients the view of "x" as an attribute.

Don't use static members unless you really intend the value to be what it is
for the entire class. If your analytical model says, "I can have two Vectors,
call them 'va' and 'vb', and they can contain separate values, and not be
equal in value to each other", then the model requires that the "values" for
Vectors be instance-level.

While you're at it, you will want to override the Object methods equals() and
hashCode(), in a consistent manner.

You also face the decision of whether to make Matrix instances immutable, in
effect "read-only" after construction. There are distinct benefits to doing
so, but it complicates objects that support calculations.

Joshua Bloch covers these overrides and immutability admirably in his book
/Effective Java/, and there are many articles on these topics. GIYF. So are
IBM DeveloperWorks and Sun's Java sites.

P.S., in UMLish diagrams and class design documentation, I model accessor and
mutator methods as attributes, not methods. At times some of my colleagues
want to change the design docs to match the physical implementation as
methods. This is, of course, working the wrong way around.

- Lew

Hi Lew,

The thing with using the static functionality is that it's an area of
use that I want to investigate.
Not only am I developing an application but I'm also expanding my
thoughtview of the language. To that
end, I am learning how best to take advantage of static vs. non-
static. In other words, I often have
the need for a class to do some utility on behalf of some other code,
but not necessarily to have
an instance, and yet, the class can bind up instance-based methods and
attributes in one place (if any
of this makes any sense).

In other words, I want Vector to represent individual instances of
unchangeable values (I don't modify a vector
but will instead, operate on it to produce another result/instance),
but I also want Vector to have operations
that can be used without requiring an instance (although in pure terms
this is not *that* likely to happen --
I won't usually ask for the unit vector without having an actual
vector to perform that operation on).

Thanks for writing.
 
Z

Zerex71

Lew said:
Don't have instance variables for x, y and z. Define the methods in terms of
the underlying, inherited array.
public double x()
{
return array [0] [0];
}
Zerex71 said:
Your last suggestion I can live with. I just wanted to use the x, y,
and z names as ways to reference.
That still leaves the question of how the array gets updated if I am
using the class in a static fashion
i.e. not setting its individual members to particular values.

Use an appropriate setBlah( double val ) method.

Or perhaps setBlah( double val, int row, int col ).

This business of hiding all attributes behind accessor methods is quite
powerful, at the cost of verbosity. A method pair "setX()" and "getX()" need
never reference an actual instance variable "x" within the black box. They
only need to present to API clients the view of "x" as an attribute.

So I'll ask a silly question - if I have an attribute (double x),
would it be permissible
to have x(double) as the setter and x() as the getter?
Don't use static members unless you really intend the value to be what it is
for the entire class. If your analytical model says, "I can have two Vectors,
call them 'va' and 'vb', and they can contain separate values, and not be
equal in value to each other", then the model requires that the "values" for
Vectors be instance-level.

In my case, nothing will be constant about *all* instances of Vector.
They will
all potentially have varying x,y,z values. So, put that way, perhaps
I need not
have member variables in a static class....I don't want to do this,
but maybe I need
a Vector class (non-static) and a VectorOps class (static).
 
P

Patricia Shanahan

Zerex71 wrote:
....
So I'll ask a silly question - if I have an attribute (double x),
would it be permissible
to have x(double) as the setter and x() as the getter?

Technically, it would work because the two methods have different
signatures.

From a human factors point of view, I don't think it is really desirable
to have two methods in the same class with the same name that do very
different things. Usually, a method with the same name as another, but
omitting a parameter, is a convenience method that does the same job
with a default value for the parameter.

Patricia
 
Z

Zerex71

Zerex71 wrote:

...


Technically, it would work because the two methods have different
signatures.

From a human factors point of view, I don't think it is really desirable
to have two methods in the same class with the same name that do very
different things. Usually, a method with the same name as another, but
omitting a parameter, is a convenience method that does the same job
with a default value for the parameter.

Patricia

But it is permissible, right? That is method overloading, if I recall
correctly.
I think with a trivial member variable like x, having getX() and
setX(double) seem to
be overkill, although I am not opposed to it.

Mike
 
P

Patricia Shanahan

Zerex71 said:
But it is permissible, right? That is method overloading, if I recall
correctly.
I think with a trivial member variable like x, having getX() and
setX(double) seem to
be overkill, although I am not opposed to it.

Depends what you mean by "permissible". I would not do it, because I set
a higher value on the principle of minimum surprise than on terseness
when designing class interfaces.

Also, thinking in terms of "a trivial member variable" is a mistake.

There is some attribute that objects of your class all have. You have
decided it is appropriate for users of the class to be able to get and
set it. That is a matter of interface design, so changing it can affect
any code that uses the class.

You have also decided, at least for now, that the attribute is best
implemented by keeping its current value in a member variable. That is
just a matter of implementation of this class, and could be changed
without any change in the interface.

Patricia
 
C

Chris Uppal

Zerex71 said:
So I'll ask a silly question - if I have an attribute (double x),
would it be permissible
to have x(double) as the setter and x() as the getter?

Yes, it's perfectly permissible, and even rather sensible (in this case).

I should warn you that it does break a fairly widely-used convention for Java,
where methods tend to come in getX()/setX(int) pairs. But it is only a
convention, and not (IMO) a particularly good one.

-- chris
 
C

Chris Uppal

Zerex71 said:
.I don't want to do this, but maybe I need
a Vector class (non-static) and a VectorOps class (static).

There is no need for that, since static members are separate from instance
members anyway. But if it helps you keep the separation clear in your head
while you are learning how to use "static" effectively, then it might be a good
idea to try for a while.

-- chris
 
Z

Zerex71

Yes, it's perfectly permissible, and even rather sensible (in this case).

I should warn you that it does break a fairly widely-used convention for Java,
where methods tend to come in getX()/setX(int) pairs. But it is only a
convention, and not (IMO) a particularly good one.

-- chris

Hi Chris,

I think part of the reason I bring this up is that when all I want to
do is set a particular value for my class (Vector, for example, but
this could apply to other classes), all I really want to do is:

MyVector.x = ...
MyVector.y = ...
MyVector.z = ...

But we're supposed to be all "OO" and everything so I'm supposed to
hide my data, right? So I have to use the overhead of
MyVector.setX(...) etc. which I think is just overkill. Plus, I agree
with the tenets of "gOOd design" but in all reality, it's not like
thousands of people are going to be using my class and strewing the
Java landscape with my class. It's one class in one application. If
I can design it to be airtight for my purposes, I think that's just
fine.

One big thing that I have discovered in my coding is that most of the
time it almost doesn't matter how I implement the class, the ultimate
thing that drives my design is the elegance, look, and soundness of
the code *when it is actually invoked*. In other words, if I do the
bottom-up thing, all's well and good until the first time I try to use
what I've coded and then I go, "Uh-oh, that doesn't look too great" so
I go back and restructure things.

Mike
 
J

John W. Kennedy

Chris said:
Yes, it's perfectly permissible, and even rather sensible (in this case).

I should warn you that it does break a fairly widely-used convention for Java,
where methods tend to come in getX()/setX(int) pairs. But it is only a
convention, and not (IMO) a particularly good one.

It's even a little bit more than a convention, in that Eclipse (I know)
and NetBeans (I suppose) will automatically generate them for you, and
in that they are mandatory in the JavaBeans architecture.
 
M

Martin Gregorie

Zerex71 said:
One big thing that I have discovered in my coding is that most of the
time it almost doesn't matter how I implement the class, the ultimate
thing that drives my design is the elegance, look, and soundness of
the code *when it is actually invoked*. In other words, if I do the
bottom-up thing, all's well and good until the first time I try to use
what I've coded and then I go, "Uh-oh, that doesn't look too great" so
I go back and restructure things.
This is a good reason for not using bottom up design. IMO top-down
design combined with incremental development is the way to go. This way
you can introduce a new class with sensible (and sensibly named)
methods, test run it as a skeleton that does little more than return
values needed to check the operation of its caller and only then, when
the logic is right, do you need to write functionality into the new class.

I really hate seeing undocumented classes (there are some in the
standard class library and more in Javamail and 3rd party packages). As
skeletal descriptions are better than none I think the outline Javadoc
descriptions are best written as part of the class skeleton and then
fleshed out as code is added to the methods.
 
A

angrybaldguy

Just to clarify Chris's response a bit:

You can safely give accessors and mutators (or any other methods) the
same name provided they have different signatures (name + arguments,
basically). That said, the getFoo/setFoo convention is VERY strongly
embedded in the Java programming culture. It's important to obey
local conventions for the simple reason that if you ever need help
with your code, you'll spend less time explaining what getX() is doing
than what x() is doing. That said...
I think part of the reason I bring this up is that when all I want to
do is set a particular value for my class (Vector, for example, but
this could apply to other classes), all I really want to do is:

MyVector.x = ...
MyVector.y = ...
MyVector.z = ...

But we're supposed to be all "OO" and everything so I'm supposed to
hide my data, right?

Yes, but accessors and mutators have very little to do with data
hiding.

- WARNING - WARNING - WARNING -
The following viewpoint is extremist and not completely practical on
all projects. Take with a grain of salt as large as needed.
- WARNING - WARNING - WARNING -

"OO" doesn't mean "I have accessors and mutators for all my member
variables". It means the code is structured around the behaviour of
each object as a whole rather than treating objects as glorified
structs. Think about *why* you want to change just one attribute of
your mathematical Vector. In fact, think carefully about why you want
to change the Vector at all.

I'm strongly opposed to mutable "value" objects; they complicate
making assertions about the thing the object represents
signifigantly. Imagine for a moment if String were mutable -- every
time you passed a String into or received a String from a method
outside your control, the contents of the String might change without
the identity of the String changing. Conversely, you'd be able to
violate "invariants" of other classes by giving them a String in a
valid state and then changing it to be an invalid state:

HashMap<String, T> stringMap = ....;
String keyA = "key a";
String keyB = "key b";

stringMap.put (keyA, valueA);
stringMap.put (keyB, valueB);

keyB.setChar(4, 'a');

And there's nothing HashMap could do to "defend" itself from this
without adding a large amount of Observer-pattern cruft to String and
complicating the class, or without copying the key Strings and using
copies instead of the original string, consuming much more memory.

To get back to Vectors and operations on them, consider working with
entire vectors at once rather than vector components. Component
operations should be encapsulated inside the Vector objects (as
instance methods) or inside the Vector class (as static methods). The
"x", "y", and "z" components may be exposed through accessors safely,
but not mutated outside the class.

Then if you need to represent a new mathematical vector, you represent
it with a new Vector instance either created with "new" or created by
operations on existing Vector instances, similar to how String's
"manipulation" methods like replace return new Strings. If you no
longer need the original Vector, dispose of it and let the GC deal
with it. If you're reasonably smart about how you use Vector objects,
you can avoid creating excess objects by keeping computed Vectors
around until you're sure you don't need them any more, which should
alleviate most "heap churn" concerns.
 
C

Chris Uppal

Zerex71 said:
One big thing that I have discovered in my coding is that most of the
time it almost doesn't matter how I implement the class, the ultimate
thing that drives my design is the elegance, look, and soundness of
the code *when it is actually invoked*.

I know what you mean, and I too have had the sad experience of designing
something which made perfect sense on its own terms but where turned out that I
hadn't given enough thought given to its "user-interface".

But I think you may be overdoing it a little. The superficial appearance of
the code is comparatively unimportant (within limits) -- less important than
semantic coherence anyway. If you have to sacrifice one to get the other (and
you /will/ have to, if you are programming in Java) then prefer clean,
manageable, and complete semantics every time.

If (once you've got the semantics right) you can tweak a few things, or
introduce a few helpers and short-cut methods, to make the client code
prettier, then that's fine. No reason not to go for it. But don't make the
mistake on not providing a coherent, complete, "ordinary", API for places where
you don't want to prettify the user code.

Sauce on top of pasta, not sauce /instead/ of pasta...

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top