Why not cloneable by default?

T

Thomas G. Marshall

Chris Smith coughed up:

....[rip]...

There are, of course, situations where merely comparing object state
is what you want; but they tend to be very context-specific in their
meaning.

Because it had not been done yet in this conversation, I figured I'd go a
take a look at the 1.5.0 source. I found 297 classes have a defined
equals(). This was found by looking for "boolean equals" with the following
unix (cygwin) command:

--> find java javax -name \*.java -exec fgrep -Hnl "boolean equals" {}
\;

Note: don't look for "public boolean equals", since it won't discover the
many declared final.

java/awt/AlphaComposite.java
java/awt/AWTKeyStroke.java
java/awt/BasicStroke.java
java/awt/Color.java
java/awt/datatransfer/DataFlavor.java
java/awt/datatransfer/MimeType.java
java/awt/datatransfer/MimeTypeParameterList.java
java/awt/Dimension.java
java/awt/DisplayMode.java
java/awt/font/FontRenderContext.java
java/awt/font/GlyphVector.java
java/awt/font/ImageGraphicAttribute.java
java/awt/font/NumericShaper.java
java/awt/font/ShapeGraphicAttribute.java
java/awt/font/TextHitInfo.java
java/awt/font/TextLayout.java
java/awt/Font.java
java/awt/geom/AffineTransform.java
java/awt/geom/Area.java
java/awt/geom/Point2D.java
java/awt/geom/Rectangle2D.java
java/awt/image/ColorModel.java
java/awt/image/ComponentColorModel.java
java/awt/image/ComponentSampleModel.java
java/awt/image/MultiPixelPackedSampleModel.java
java/awt/image/PackedColorModel.java
java/awt/image/SinglePixelPackedSampleModel.java
java/awt/Insets.java
java/awt/JobAttributes.java
java/awt/MenuShortcut.java
java/awt/PageAttributes.java
java/awt/Point.java
java/awt/Rectangle.java
java/awt/RenderingHints.java
java/beans/DefaultPersistenceDelegate.java
java/beans/IndexedPropertyDescriptor.java
java/beans/MetaData.java
java/beans/PropertyDescriptor.java
java/beans/ReflectionUtils.java
java/io/File.java
java/io/FilePermission.java
java/io/ObjectStreamClass.java
java/lang/annotation/Annotation.java
java/lang/Boolean.java
java/lang/Byte.java
java/lang/Character.java
java/lang/Double.java
java/lang/Enum.java
java/lang/Float.java
java/lang/Integer.java
java/lang/Long.java
java/lang/Object.java (well duh... :) )
java/lang/ProcessEnvironment.java
java/lang/reflect/Constructor.java
java/lang/reflect/Field.java
java/lang/reflect/Method.java
java/lang/Short.java
java/lang/Shutdown.java
java/lang/StackTraceElement.java
java/lang/String.java
java/math/BigDecimal.java
java/math/BigInteger.java
java/math/MathContext.java
java/net/Inet4Address.java
java/net/Inet6Address.java
java/net/InetAddress.java
java/net/InetSocketAddress.java
java/net/NetworkInterface.java
java/net/Proxy.java
java/net/SocketPermission.java
java/net/URI.java
java/net/URL.java
java/net/URLStreamHandler.java
java/nio/ByteBuffer.java
java/nio/CharBuffer.java
java/nio/charset/Charset.java
java/nio/DoubleBuffer.java
java/nio/FloatBuffer.java
java/nio/IntBuffer.java
java/nio/LongBuffer.java
java/nio/ShortBuffer.java
java/rmi/activation/ActivationDesc.java
java/rmi/activation/ActivationGroupDesc.java
java/rmi/activation/ActivationGroupID.java
java/rmi/activation/ActivationID.java
java/rmi/dgc/VMID.java
java/rmi/MarshalledObject.java
java/rmi/server/ObjID.java
java/rmi/server/RemoteObject.java
java/rmi/server/UID.java
java/security/AccessControlContext.java
java/security/acl/Permission.java
java/security/AllPermission.java
java/security/BasicPermission.java
java/security/cert/Certificate.java
java/security/cert/CertPath.java
java/security/cert/X509CRL.java
java/security/cert/X509CRLEntry.java
java/security/CodeSigner.java
java/security/CodeSource.java
java/security/Identity.java
java/security/Permission.java
java/security/Principal.java
java/security/Provider.java
java/security/spec/ECFieldF2m.java
java/security/spec/ECFieldFp.java
java/security/spec/ECPoint.java
java/security/spec/EllipticCurve.java
java/security/Timestamp.java
java/security/UnresolvedPermission.java
java/sql/Timestamp.java
java/text/AttributedCharacterIterator.java
java/text/AttributedString.java
java/text/ChoiceFormat.java
java/text/CollationKey.java
java/text/Collator.java
java/text/DateFormat.java
java/text/DateFormatSymbols.java
java/text/DecimalFormat.java
java/text/DecimalFormatSymbols.java
java/text/DigitList.java
java/text/FieldPosition.java
java/text/MessageFormat.java
java/text/NumberFormat.java
java/text/ParsePosition.java
java/text/PatternEntry.java
java/text/RuleBasedBreakIterator.java
java/text/RuleBasedCollator.java
java/text/SimpleDateFormat.java
java/text/StringCharacterIterator.java
java/util/AbstractList.java
java/util/AbstractMap.java
java/util/AbstractSet.java
java/util/Arrays.java
java/util/BitSet.java
java/util/Calendar.java
java/util/Collection.java
java/util/Collections.java
java/util/Comparator.java
java/util/concurrent/ConcurrentHashMap.java
java/util/concurrent/CopyOnWriteArrayList.java
java/util/Date.java
java/util/EnumMap.java
java/util/GregorianCalendar.java
java/util/HashMap.java
java/util/Hashtable.java
java/util/IdentityHashMap.java
java/util/jar/Attributes.java
java/util/jar/Manifest.java
java/util/JumboEnumSet.java
java/util/List.java
java/util/Locale.java
java/util/logging/Level.java
java/util/Map.java
java/util/PropertyPermission.java
java/util/RegularEnumSet.java
java/util/ResourceBundle.java
java/util/Set.java
java/util/SimpleTimeZone.java
java/util/TreeMap.java
java/util/UUID.java
java/util/Vector.java
java/util/WeakHashMap.java
javax/imageio/ImageTypeSpecifier.java
javax/management/Attribute.java
javax/management/MBeanAttributeInfo.java
javax/management/MBeanConstructorInfo.java
javax/management/MBeanFeatureInfo.java
javax/management/MBeanInfo.java
javax/management/MBeanNotificationInfo.java
javax/management/MBeanOperationInfo.java
javax/management/MBeanParameterInfo.java
javax/management/MBeanPermission.java
javax/management/MBeanServerPermission.java
javax/management/modelmbean/DescriptorSupport.java
javax/management/ObjectInstance.java
javax/management/ObjectName.java
javax/management/openmbean/ArrayType.java
javax/management/openmbean/CompositeData.java
javax/management/openmbean/CompositeDataSupport.java
javax/management/openmbean/CompositeType.java
javax/management/openmbean/OpenMBeanAttributeInfo.java
javax/management/openmbean/OpenMBeanAttributeInfoSupport.java
javax/management/openmbean/OpenMBeanConstructorInfo.java
javax/management/openmbean/OpenMBeanConstructorInfoSupport.java
javax/management/openmbean/OpenMBeanInfo.java
javax/management/openmbean/OpenMBeanInfoSupport.java
javax/management/openmbean/OpenMBeanOperationInfo.java
javax/management/openmbean/OpenMBeanOperationInfoSupport.java
javax/management/openmbean/OpenMBeanParameterInfo.java
javax/management/openmbean/OpenMBeanParameterInfoSupport.java
javax/management/openmbean/OpenType.java
javax/management/openmbean/SimpleType.java
javax/management/openmbean/TabularData.java
javax/management/openmbean/TabularDataSupport.java
javax/management/openmbean/TabularType.java
javax/management/remote/JMXPrincipal.java
javax/management/remote/JMXServiceURL.java
javax/naming/BinaryRefAddr.java
javax/naming/CompositeName.java
javax/naming/CompoundName.java
javax/naming/directory/BasicAttribute.java
javax/naming/directory/BasicAttributes.java
javax/naming/ldap/LdapName.java
javax/naming/ldap/Rdn.java
javax/naming/NameImpl.java
javax/naming/RefAddr.java
javax/naming/Reference.java
javax/print/attribute/AttributeSet.java
javax/print/attribute/AttributeSetUtilities.java
javax/print/attribute/DateTimeSyntax.java
javax/print/attribute/HashAttributeSet.java
javax/print/attribute/IntegerSyntax.java
javax/print/attribute/ResolutionSyntax.java
javax/print/attribute/SetOfIntegerSyntax.java
javax/print/attribute/Size2DSyntax.java
javax/print/attribute/standard/Copies.java
javax/print/attribute/standard/CopiesSupported.java
javax/print/attribute/standard/DateTimeAtCompleted.java
javax/print/attribute/standard/DateTimeAtCreation.java
javax/print/attribute/standard/DateTimeAtProcessing.java
javax/print/attribute/standard/Destination.java
javax/print/attribute/standard/DocumentName.java
javax/print/attribute/standard/JobHoldUntil.java
javax/print/attribute/standard/JobImpressions.java
javax/print/attribute/standard/JobImpressionsCompleted.java
javax/print/attribute/standard/JobImpressionsSupported.java
javax/print/attribute/standard/JobKOctets.java
javax/print/attribute/standard/JobKOctetsProcessed.java
javax/print/attribute/standard/JobKOctetsSupported.java
javax/print/attribute/standard/JobMediaSheets.java
javax/print/attribute/standard/JobMediaSheetsCompleted.java
javax/print/attribute/standard/JobMediaSheetsSupported.java
javax/print/attribute/standard/JobMessageFromOperator.java
javax/print/attribute/standard/JobName.java
javax/print/attribute/standard/JobOriginatingUserName.java
javax/print/attribute/standard/JobPriority.java
javax/print/attribute/standard/JobPrioritySupported.java
javax/print/attribute/standard/Media.java
javax/print/attribute/standard/MediaPrintableArea.java
javax/print/attribute/standard/MediaSize.java
javax/print/attribute/standard/NumberOfDocuments.java
javax/print/attribute/standard/NumberOfInterveningJobs.java
javax/print/attribute/standard/NumberUp.java
javax/print/attribute/standard/NumberUpSupported.java
javax/print/attribute/standard/OutputDeviceAssigned.java
javax/print/attribute/standard/PageRanges.java
javax/print/attribute/standard/PagesPerMinute.java
javax/print/attribute/standard/PagesPerMinuteColor.java
javax/print/attribute/standard/PrinterInfo.java
javax/print/attribute/standard/PrinterLocation.java
javax/print/attribute/standard/PrinterMakeAndModel.java
javax/print/attribute/standard/PrinterMessageFromOperator.java
javax/print/attribute/standard/PrinterMoreInfo.java
javax/print/attribute/standard/PrinterMoreInfoManufacturer.java
javax/print/attribute/standard/PrinterName.java
javax/print/attribute/standard/PrinterResolution.java
javax/print/attribute/standard/PrinterURI.java
javax/print/attribute/standard/QueuedJobCount.java
javax/print/attribute/standard/RequestingUserName.java
javax/print/attribute/TextSyntax.java
javax/print/attribute/URISyntax.java
javax/print/DocFlavor.java
javax/print/MimeType.java
javax/print/PrintService.java
javax/rmi/CORBA/Stub.java
javax/rmi/CORBA/StubDelegate.java
javax/rmi/ssl/SslRMIClientSocketFactory.java
javax/rmi/ssl/SslRMIServerSocketFactory.java
javax/security/auth/kerberos/DelegationPermission.java
javax/security/auth/kerberos/KerberosPrincipal.java
javax/security/auth/kerberos/ServicePermission.java
javax/security/auth/PrivateCredentialPermission.java
javax/security/auth/Subject.java
javax/security/auth/x500/X500Principal.java
javax/sound/midi/MidiDevice.java
javax/sound/midi/Sequencer.java
javax/sound/sampled/AudioFileFormat.java
javax/sound/sampled/AudioFormat.java
javax/sound/sampled/Control.java
javax/sound/sampled/LineEvent.java
javax/sound/sampled/Mixer.java
javax/sound/sampled/Port.java
javax/sound/sampled/ReverbType.java
javax/swing/KeyboardManager.java
javax/swing/plaf/metal/CachedPainter.java
javax/swing/plaf/synth/ParsedSynthStyle.java
javax/swing/text/DefaultCaret.java
javax/swing/text/html/HTML.java
javax/swing/text/SimpleAttributeSet.java
javax/swing/text/StyleContext.java
javax/swing/text/TabSet.java
javax/swing/text/TabStop.java
javax/swing/tree/TreePath.java
javax/xml/datatype/Duration.java
javax/xml/datatype/XMLGregorianCalendar.java
javax/xml/namespace/QName.java
 
J

John C. Bollinger

Thomas said:
Chris Smith coughed up:
[...]
I also dislike marker interfaces.


That purist side of you is relentless. :) I personally like the ability to
mark certain classes for the sole of inclusion to a particular group.

No one is going to try to take that away from you, but please forgive me
if I don't see the point. One of the major complaints about Cloneable
is precisely that it is a marker interface (i.e. that it doesn't specify
a clone() method). A difference between that case and your example is
that Cloneable is supposed to imply something about the behavior of
instances, whereas your suggested use isn't. I markers of the former
kind are broken, and I don't have much use for the latter kind.

I am wary of this idea, but it may be a good one. I haven't yet fully
grasped the scope and nature of the new annotations feature.

If we don't use marker interfaces, then that resolves my issue with
them. :)
 
T

Thomas G. Marshall

John C. Bollinger coughed up:
Thomas said:
Chris Smith coughed up:
I dislike marker interfaces,
[...]
I also dislike marker interfaces.


That purist side of you is relentless. :) I personally like the
ability to mark certain classes for the sole of inclusion to a
particular group.

No one is going to try to take that away from you, but please forgive
me if I don't see the point. One of the major complaints about
Cloneable is precisely that it is a marker interface (i.e. that it
doesn't specify a clone() method).


Yes, /of course/. That point was certainly not lost on me.

I was responding to Chris Smith's statement as if it were a general one,
which I believe it is. I've heard it before. It seems to give OO purists
the case of the willies because a contract that specifies nothing is not
really a contract, or so their argument seems to me. Whatever: this is a
distraction.



--
Enough is enough. It is /not/ a requirement that someone must google
relentlessly for an answer before posting in usenet. Newsgroups are
for discussions. Discussions do /not/ necessitate prior research. If
you are bothered by someone asking a question without taking time to
look something up, simply do not respond.
 
J

John C. Bollinger

Thomas said:
The problem comes in when you are deep copying something that contains deep
within it a reference to an object that /must/ be shared with a completely
different object deep within another object. There is no way to tell when
an object must be duplicated or shared.

I hesitate to say that there is _no_ way to tell, but I agree that this
is a fairly hard problem.
Furthermore, deep cloning without regard to use would likely result in
objects that at first glance only "seem" to work.

I agree. I have been devoting some thought to how we might design
/anything/ that provides a context-sensitive, safe, and appropriate
mechanism for any kind of deep copying, but I don't know whether I have
a chance of succeeding on all fronts.
 
B

Bent C Dalager

Each team, therefore, has a collection of students, and a student has a
first and last name. There's a separate data structure that keeps track
of which students wish to compete in which events. I don't care if two
students on the team have the same name. I only care that the right
events are associated with the right objects.

At some point, you will probably want to map this back into the real
world. You might, for example, want to post lists on a notice board to
tell everyone who is on which team. How do you achieve this if the
computer system doesn't care which John Smith is which?
When I associate the students with an event, they end up acting as keys
in a HashMap, and it would be a disaster if I chose to override the
"equals" method to compare their names (which is the only field of the
Student class). I wisely decided that these objects should inherit the
concept of equality from Object. This means that I'm able to make use
of an object's identity; something which is a fundamental concept of OO
programming and is quite useful for solving this kind of problem.

It is not my position that you should implement an equals() that is
inconsistent with the use to which the objects will be put. I
certainly see the value in keeping Object's equals() in a great many
cases. I do not, however, see how this rules out other uses.
I didn't mean property as "field" or in the JavaBeans sense. I meant it
in the general sense. Perhaps "feature" would be better, since it
doesn't seem to be widely used for a programming language concept. So
read the above as "identity is its own feature of an object...".

I don't disagree that an object's memory address could be used to
distinguish it from other objects of the same type. I do disagree that
this is the only sensible way of identifying one though.
It's a problem because comparing the cars involved in the two traffic
camera readings is not equality. In order for a method to be
overridden, you need to provide an implementation that's meaningful in
the context of the class that defines the method. Your implementation
of equals is only useful in a situation where you know that both objects
are traffic camera readings, and you know that you only want to compare
a certain subset of their state. In that case, you may as well write
your own method, and it won't cause such problems if you later decide
that you need to store readings in a different data structure.

The implementation is not specific to traffic camera readings; it is
equally usable whenever you have obtained car data from wherever and
need to find out if this is the same car as that produced by some
other reading.

You are correct that it is not usable for _all_ contexts in which you
may want to compare cars, but then it is not meant to be. It is only
meant to be useful in the most typical cases. If you want to compare
cars by their colour, you will have to implement that algorithm
separately.

Cheers
Bent D
 
L

Lee Fesperman

Chris said:
In order to store MindIQ employees in a database, you would need to
create some kind of artificial key to ensure uniqueness in a relational
database. You don't necessarily need to use the auto-increment column
feature of the database; but if you chose instead to tell us, "assign
your own damned employee numbers", then we would just find a different
provider for our software.

You seem convinced that an artifical key is appropriate for a relational design. This
ain't OO, you know. I can provide links to show you that this approach is harmful.
Normally, you will to need to use the database to accomplish your own work. Demanding
your own concept of proper relational design will ultimately harm you and others in the
company.
 
C

Chris Smith

Bent C Dalager said:
At some point, you will probably want to map this back into the real
world. You might, for example, want to post lists on a notice board to
tell everyone who is on which team. How do you achieve this if the
computer system doesn't care which John Smith is which?

As it turns out, I don't want to do that. If I did, it would not pose a
problem; the printed report would just include the name "John Smith"
twice for a team. No problem at all.

The one thing that I KNOW I don't want to do is give everyone a
"competitor number" or some such thing to differentiate between the
various students. It would be a major administrative hassle, and would
serve absolutely no purpose whatsoever.
It is not my position that you should implement an equals() that is
inconsistent with the use to which the objects will be put. I
certainly see the value in keeping Object's equals() in a great many
cases. I do not, however, see how this rules out other uses.

In this particular part of the discussion, we are discussing that
objects have identity, and that's it's not a good idea to ignore that
foundational principle of OO design.
I don't disagree that an object's memory address could be used to
distinguish it from other objects of the same type. I do disagree that
this is the only sensible way of identifying one though.

It is, however, what is meant by "identity" in object-oriented design.
If the object identity (you can say it's memory address if you like,
since two distinct objects will have two different memory addresses) is
discarded, that's fine; but you don't have an object any longer. You
have a value.
You are correct that it is not usable for _all_ contexts in which you
may want to compare cars, but then it is not meant to be. It is only
meant to be useful in the most typical cases. If you want to compare
cars by their colour, you will have to implement that algorithm
separately.

I don't know why you keep bringing up a search by color. I never did
bring it up, and I don't understand what you're trying to accomplish by
telling me that I'm wrong to bring it up (which, of course, I never
did). In any case, we're not talking about two objects having colors
that are equal to each other; we're talking about two objects *being*
equal to each other.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Lee Fesperman said:
You seem convinced that an artifical key is appropriate for a relational
design. This ain't OO, you know. I can provide links to show you that
this approach is harmful. Normally, you will to need to use the database
to accomplish your own work. Demanding your own concept of proper
relational design will ultimately harm you and others in the company.

You're welcome to propose another design that meets the set of
requirements being discussed, and I'll certainly listen. The only thing
you *can't* do is change the requirements in the interest of "good"
relational design. Good design -- of any variety -- is that which meets
the requirements, not that which imposes unneeded burdens on the user
because of ideological purity.

So I'm waiting for a relational database design that:

1) Does not use artificial keys (you're saying they arent' needed).

2) Does not require the input of unique identifying information such as
an employee number.

Until then, your statement that artificial keys are "harmful" is
pointless, because not being able to deliver software that meets the
requirements at all is bound to be more harmful than the disadvantages
of artificial keys.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
L

Lee Fesperman

Chris said:
You're welcome to propose another design that meets the set of
requirements being discussed, and I'll certainly listen. The only thing
you *can't* do is change the requirements in the interest of "good"
relational design. Good design -- of any variety -- is that which meets
the requirements, not that which imposes unneeded burdens on the user
because of ideological purity.

So I'm waiting for a relational database design that:

1) Does not use artificial keys (you're saying they arent' needed).

2) Does not require the input of unique identifying information such as
an employee number.

I didn't say artifical keys aren't needed; I said they shouldn't be used. Your
pejorative comments about ideological purity and unneeded burdens aside, these are
legitimate concerns in creating a usable system. A system that performs the wrong
actions and produces incorrect results is much more burdensome.

Sure, the 'business' people should define the business rules. However, when they are
incomplete, the software designers need to ask for clarification. You've never been in
the position of asking a business person for clarification? The last one I asked wanted
me to make the decision. I think not! I got in a lot of trouble for refusing, because my
predecessor was always willing to. The business person felt needlessly burdened.

If clarifications are not forthcoming, problems are sure to arise. For instance, MindIQ
hires someone else named 'Chris Smith'. Later, they request the software to give Chris
Smith a raise. Either the software performs a potentially incorrect action (that is, it
makes a guess, a business decision), or it asks them which Chris Smith or both? What
would the reply be? "The one in the green sweater" ;^)
Until then, your statement that artificial keys are "harmful" is
pointless, because not being able to deliver software that meets the
requirements at all is bound to be more harmful than the disadvantages
of artificial keys.

Delivering software based on incomplete business requirements is virtually guaranteed to
be harmful.

Note: If artificial keys are used in the scenario mentioned above, your answer to the
question would have to specify the artificial key(s) associated with the correct Chris
Smith(s). Do you see that as reasonable?

As to the disadvantages of artificial keys, do you know what they are? You weren't
interested in the information I offered on the subject.
 
C

Chris Smith

Lee Fesperman said:
If clarifications are not forthcoming, problems are sure to arise. For instance, MindIQ
hires someone else named 'Chris Smith'. Later, they request the software to give Chris
Smith a raise. Either the software performs a potentially incorrect action (that is, it
makes a guess, a business decision), or it asks them which Chris Smith or both? What
would the reply be? "The one in the green sweater" ;^)

The reply would generally be implicit in the context. For example, the
user will have just looked at the employees assigned to a particular
software project, and will choose one. The fact that there's a Chris
Smith in accounting is irrelevant.

Of course, as mentioned in an email to Bent, with whom this conversation
started, this is a poor example. In practice, there would be *some*
identifying property of the employee that's useful as a primary key; for
example, social security number or some such thing. More often, the
objects that depend on identity in a relational system do not represent
substantial business objects, but are part of data structures.

However, identity should still be provided in representing data within
an OO system.
Note: If artificial keys are used in the scenario mentioned above, your answer to the
question would have to specify the artificial key(s) associated with the correct Chris
Smith(s). Do you see that as reasonable?

Yes, I certainly see it as reasonable that the application code should
have knowledge of the database key.
As to the disadvantages of artificial keys, do you know what they are? You weren't
interested in the information I offered on the subject.

Frankly, this discussion is about something completely different. If
you want to say something, then you have every right to say it; but no
I'm not particularly longing for the information.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Thomas G. Marshall

Lee Fesperman coughed up:

....[rip]...
Lee Fesperman <[email protected]> wrote:
....[rip]...
[...] Demanding your own
concept of proper relational design will ultimately harm you and
others in the company.
....[rip]...

I didn't say artifical keys aren't needed; I said they shouldn't be
used. Your pejorative comments about ideological purity and unneeded
burdens aside [...]


Lee, you need to be aware that there is an air of confrontation and an
undercurrent of insult in your conversation style that I don't see from
Chris Smith. Take it or leave it, but while I don't think I agree with
Chris on this subject, he has been very polite here.

....[rip]...
 
D

Dimitri Maziuk

Chris Smith sez:
.... In practice, there would be *some*
identifying property of the employee that's useful as a primary key; for
example, social security number or some such thing.

Hehe. Fingerprint, retina scan, or DNA print. Everything else
is an atificial key -- perhaps not assigned by your database, but
nonetheless. (SSN comes with an additional feature that it should
be illegal to ask for it, if it isn't already in your jurisdiction.)

Dima
 
L

Lee Fesperman

Thomas said:
Lee Fesperman coughed up:

...[rip]...
Lee Fesperman <[email protected]> wrote:
...[rip]...
[...] Demanding your own
concept of proper relational design will ultimately harm you and
others in the company.
...[rip]...

I didn't say artifical keys aren't needed; I said they shouldn't be
used. Your pejorative comments about ideological purity and unneeded
burdens aside [...]

Lee, you need to be aware that there is an air of confrontation and an
undercurrent of insult in your conversation style that I don't see from
Chris Smith. Take it or leave it, but while I don't think I agree with
Chris on this subject, he has been very polite here.

...[rip]...

Hi Thomas,

I have to agree that some discussions between you and me have been confrontational, even
insulting. However, I don't see that as the case here. Chris did characterize my remarks
as being concerned with ideological purity and being a unneeded burden. Frankly, calling
me a ideological purist is confrontational. I also believe there is an undercurrent in
his remarks relating to some arguments that occurred on c.l.j.d.

If you are actually referring to my comments to the point that an improper relational
design can be harmful, I have to stand by that assertion. I have seen such problems a
number of times, even leading to grievous financial penalties.

Perhaps, as a third party, you can help me see the light. I have been trying to tone
down my remarks on c.l.j.p lately, even apologizing for some comments.
 
L

Lee Fesperman

Chris said:
The reply would generally be implicit in the context. For example, the
user will have just looked at the employees assigned to a particular
software project, and will choose one. The fact that there's a Chris
Smith in accounting is irrelevant.

Of course, as mentioned in an email to Bent, with whom this conversation
started, this is a poor example. In practice, there would be *some*
identifying property of the employee that's useful as a primary key; for
example, social security number or some such thing. More often, the
objects that depend on identity in a relational system do not represent
substantial business objects, but are part of data structures.

Hmm, I generally see the purpose of a relational database is to model real world
(business, as it were) entities. Arbitrary internal (computer) data wouldn't seem to fit
that scenario and perhaps would be a place where artificial keys were appropriate.
However at this point, relational concepts like normalization, functional dependencies
don't seem to apply. The database here is functioning basically as a repository of
arbitrary data with little inherent structure. While this is a possible application of a
database, the more general organizing concepts have little use. OTOH, we weren't
discussing this kind of application (recently).
However, identity should still be provided in representing data within
an OO system.

Yes, that is a completely different matter.
Yes, I certainly see it as reasonable that the application code should
have knowledge of the database key.

Agreed, but I was referring to user/operator knowledge of the internal key.
Frankly, this discussion is about something completely different. If
you want to say something, then you have every right to say it; but no
I'm not particularly longing for the information.

Yes, we're getting pretty far off topic. If you remember, we went down this track after
I posted a response agreeing with your comments that mixing OO concepts and relational
ones in an OO design was inappropriate (weird). Then, I added an enquiry about
situations where you thought an artificial key was appropriate in a relational design,
leading us down this sub-thread (actually, above you did touch on such a case.)
 
T

Thomas G. Marshall

Lee Fesperman coughed up:

....[rip]...
I have been
trying to tone down my remarks on c.l.j.p lately, even apologizing
for some comments.

It is common for people to try to hand wave away their prior attitude issues
when they are pointed out by others, and you're not doing that, but it is
*very* uncommon to actually attempt to fix it, or even ponder if it needs
fixing as you seem to be doing. Not to get too drippy, but regardless as to
whether or not you feel you need to change at all, it is the act of
evaluating itself that I think is rare and very impressive on your part.

If you want to chat about what I think does and does not work to mitigate
online ire, we should probably do the rest by email. But my knowledge on
the subject is hardly insightful and is based mostly upon who draws first
blood, and what constitutes first blood. And that is really tricky. I have
no clue where the high road is on the map, but I'm usually startled when
someone believes that I've been unfair with them---there are so many ways of
reading inflection and intent in any given sentence.
 
C

Chris Smith

Lee Fesperman said:
Hmm, I generally see the purpose of a relational database is to model real world
(business, as it were) entities.

Yup. To add to the confusion, I said "relational" when I meant "OO".
The last sentence should read: "More often, the objects that depend on
identity in an OO system do not represent substantial business objects,
but are part of data structures."

Interestingly enough, such cases are indeed the places where object
identity as a separate concept from state is often useful, and they do
correspond with places things that won't be stored in a database. They
are *not* areas where artificial keys are needed, specifically because
of the point here; artificial keys are never needed in an OO
application.

I do, nevertheless, still see cases where an artificial key is necessary
in a database. If, for example, I changed my Science Olympiad
tournament software that I've been describing to Brent to use a database
(currently it doesn't); I would still need to represent a lot of
statements of the form "there is a student competing in events A, B, and
D", without necessarily knowing any identifying information about that
student -- even the name is optional. To do that, I'd need to find some
kind of a unique identifier somewhere to use as a foreign key in other
tables. A table with no fields (or a lot of NULLs in the one existing
field) doesn't do much good in terms of defining relationships.
Agreed, but I was referring to user/operator knowledge of the internal key.

Then no, I don't see any reason to tell the user about the artificial
key.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Thomas said:
Lee, you need to be aware that there is an air of confrontation and an
undercurrent of insult in your conversation style that I don't see from
Chris Smith.

I really don't see a problem myself, except that Lee and I obviously
disagree about whether "ideological purist" is an insult. I regarded it
as mostly a neutral term, but Lee clearly took offense.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
L

Lee Fesperman

Chris said:
Yup. To add to the confusion, I said "relational" when I meant "OO".
The last sentence should read: "More often, the objects that depend on
identity in an OO system do not represent substantial business objects,
but are part of data structures."

Interestingly enough, such cases are indeed the places where object
identity as a separate concept from state is often useful, and they do
correspond with places things that won't be stored in a database. They
are *not* areas where artificial keys are needed, specifically because
of the point here; artificial keys are never needed in an OO
application.

I'm not sure what you mean here. I would tend to call object identity an "artificial
keys", however discussing keys in the database sense seems out of place in an OO
discourse.
I do, nevertheless, still see cases where an artificial key is necessary
in a database. If, for example, I changed my Science Olympiad
tournament software that I've been describing to Brent to use a database
(currently it doesn't); I would still need to represent a lot of
statements of the form "there is a student competing in events A, B, and
D", without necessarily knowing any identifying information about that
student -- even the name is optional. To do that, I'd need to find some
kind of a unique identifier somewhere to use as a foreign key in other
tables. A table with no fields (or a lot of NULLs in the one existing
field) doesn't do much good in terms of defining relationships.

Certainly, table or even a row with all NULLs is ridiculous ... sort of a bunch of
nothing about nothing ;^)

I didn't pick up on that discussion about tournament software. I'm afraid I clicked it
away after a quick read through, so I can't really comment about the appropriateness of
artificial keys in this case. Perhaps I'll get a chance to check it out on Google
groups.
Then no, I don't see any reason to tell the user about the artificial
key.

My original question was posed to the user/operator --- which Chris Smith gets the
raise? ... thus requiring the user to specify the artificial key to distinguish. I think
I will just let this pass. You seem to have little interest in pursuing this OT tangent.
 
B

Bent C Dalager

As it turns out, I don't want to do that. If I did, it would not pose a
problem; the printed report would just include the name "John Smith"
twice for a team. No problem at all.

That is fine then, for the special case of not having to tell people
apart after processing. I don't have a problem with that and I can see
how it may be useful.
The one thing that I KNOW I don't want to do is give everyone a
"competitor number" or some such thing to differentiate between the
various students. It would be a major administrative hassle, and would
serve absolutely no purpose whatsoever.

If they are students, they will probably have some unique student
number anyway in which case synthesizing a new one might not be
necessary even if you did need to be able to tell them apart
after processing.
In this particular part of the discussion, we are discussing that
objects have identity, and that's it's not a good idea to ignore that
foundational principle of OO design.

In Java, that is provided by the == operator. I still don't see why
that should have consequences for the use of the equals() method.
It is, however, what is meant by "identity" in object-oriented design.
If the object identity (you can say it's memory address if you like,
since two distinct objects will have two different memory addresses) is
discarded, that's fine; but you don't have an object any longer. You
have a value.

I take it that you mean to say that not everything that is a Java
object is an OO object? If so, then I might not have a problem with
that. I am referring to the use of the equals() method on Java objects
and if my use turns these Java objects conceptually into OO values
that is not a problem. In this case, our disagreement is based on a
misunderstanding of terminology.
I don't know why you keep bringing up a search by color. I never did
bring it up, and I don't understand what you're trying to accomplish by
telling me that I'm wrong to bring it up (which, of course, I never
did).

I don't believe I ever claimed that you did. If so, please point me to
it and I will address it.

Cheers
Bent D
 
L

Lee Fesperman

Chris said:
I really don't see a problem myself, except that Lee and I obviously
disagree about whether "ideological purist" is an insult. I regarded it
as mostly a neutral term, but Lee clearly took offense.

I did say I considered it 'confrontational', as I did other aspects of your response
(specifically, the business rules challenge). I don't really consider it an insult. I
was mainly perturbed by your name-calling which I saw as a way to avoid a reasonable
discussion of the topic.

I was talking about relational concepts. RM has a solid logic, mathematics foundation
plus a comprehensive design technique -- normalization. OTOH, OO is little more than a
set of ad-hoc techniques that were known and used (by good programmers) since the 60's.
While I agree that OO is by far the best mainstream programming technique, I don't see
it holding a candle the rigorous, well-researched concepts in RM.

I'd be more likely to call some of the strongly held ideas about OO ideological purism,
because they are little more than opinions. For example, your strong opinions about
equals() ... as I said I agree with many, but I wouldn't always go that far. In our
DBMS, we use Java as the stored procedure language, static methods serving as stored
procedures. In order to provide input/output parameter semantics, we created some
mutable wrapper classes -- MutableInteger, MutableBigDecimal, MutableDouble,
MutableString, ... Their implementations include both equals() and hashCode(), because
we felt it might be useful in some cases. We do, however, include in their javadocs
caveats about their use with certain collection classes, because they are mutable
wrappers. Other collection class aspects seem workable like List#contains(), which uses
equals() but doesn't need to be repeatable.
 

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
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top