Originally posted by Pavel Kubal: Now it makes sense
For a moment, consider the question - What exactly makes sense about copying array elements here and there? Let's look at an array.
An array is a construct that exposes a contract containing three operations. These operations are symbiotic - they cannot be separated. You can define these operations as: 1. E get(int) signals NoSuchIndex 2. void set(E, int) signals NoSuchIndex 3. int getLength You can formally express the requirement of each operation, but paraphrasing is easier in communication.
The getLength operation is monadic - it forever returns the same value. The set operation exists to have an observbable side effect on the get operation. In other words, there is a unidirectional relationship from the set operation and the get operation - the set operation has no legitimate existence without the get operation. The get operation may exist in isolation - it is not monadic. The get or set operation may signal to the client the inability to perform the requested operation - the signal name is NoSuchIndex. This signal isused in the event that the client exceeds the permitted bounds (which can be found through the getLength) operation.
There is nothing (not quite true - see below) more to an array contract. How do you produce a different contract implementation with its own identity? Simply, how do you copy an array? You *must* copy elements since arrays are bound by a certain model of representation - this is an abstraction leak that is intrinsic to arrays. In fact, if arrays were nothing more than the above contract, you could implement a "unique contract implementation identity copy" without ever copying elements. Performance bigotry aside, the biggest benefit is that you have met your requirements with greater accuracy by eliminating excess - clients never know, or care, about how you have met their requirement (remember, this was not to copy an array, but to obtain a unique contract implementation identity representing the same "state" of some other contract).
This is exactly the premise that is used for net.tmorris.adt.sequence.Sequence and since the type is immutable (all operations monadic), there is never a legitimate use case for acknowledging contract implementation identity. You can perform, for example, an "append" using net.tmorris.adt.sequence.AppendSequence to be provided with a Sequence contract implementation that appears to have had elements appended.
The question arises, if Sequence is immutable, and I get a Sequence that has a greater length with additional elements, how can an element copy *not* occur? The problem here is that the premise of the question is contrived. Specifically, this part "I get a Sequence that has a greater length with additional elements". This did not occur at all since this is an invalid requirement. I merely obtain a contract implementation identity that met some formal requirement. That I have applied additional context by referring to "additional elements" or whatever it might be, is purely for my own convenience in conceptualisation of the software at hand and unrelated. It is important that it be understood the limitations of such a conceptualisation.
That ends my rant. Bye [ March 09, 2006: Message edited by: Tony Morris ]
Be careful with usage of Clone as it does only a Shalow Copy.!!
Java Objects passed by Reference ?? -> you are a failure !!
Joined: Sep 16, 2005
Another thing one could mention about the clone methods for array types (which has nothing to do with clone per se) is that in 1.5 they make use of covariant return types. This means that the signature for String's clone, for example, is:
Apart from normal use of clone as specified Sun and Others, one can use clone innovatively for creating classes in runtime without reflection,etc.
This can be really useful for a case of Classes(various strategies) -- which are derived from a common base class, to be executed for different conditions(strategies)
As sun's clone is too-many if's-but's(for good cause/safety), I have implemented my-own close with an hierarchy of classes which do use creative use of clone. I named my method to create(instead of clone and to stop its unwanted checks/restrictions in my code). I not here saying clone can't be used in my case -- what I am suggesting is another way using clone in practical applications.
So concept is like this:
Have a parent class have an abstract methods in Base-class with create method and some doJob/run,preJob/postJob methods for doing real work
Let is child class implement the create method which will do a new of that child class . Also child class implements some get/set methods and doJob/run for doinf real-work.
When JVM has started , register of all child classes in static Map with public methods to get an instance of that class(with a key of string/integer/some-key) . This could be also from a property file with class-names versus some string/integer/some-key
In a class where we need to create different child class for different strategy, get the instance of child-class by passing appropriate key.
Now create appropriate child class by calling create method. Do any pre processing in that child class instance by using preJob. Then call doJob/doJob/run. After the that call postJob.
By use in this way one can add more strategies or handlers(without using Reflection/switch case statements).
Same methodolgy can applied on other languages -- C,C++,etc
You're describing a sort of degenerate "Abstract Factory" pattern; usually the factory class (the one with the "create" method) is a separate class from the product class (the one that is created.) See here for more of a description.
Originally posted by Ernest Friedman-Hill: You're describing a sort of degenerate "Abstract Factory" pattern; usually the factory class (the one with the "create" method) is a separate class from the product class (the one that is created.) See here for more of a description.
As I said earlier, you can use clone if you can.
Definetely I used "Abstract Factory" pattern, but it is not a degenrate case . Even in ""Abstract Factory" pattern case, how one can generate classes in runtime with these conditions these may depends on restrictions on practical situation that arised in my case)
One cannot use Reflection -- for performace reasons
One cannot implement Cloneable interface in the class heirarchy( the said base/some-sub classes cannot implement Cloneable interface)
Similiar code/pattern should be used in corresponding C/C++ code(that complements java code)
Use of switch case in "Abstract Factory" implementation is prohibited -- for obvious reasons of long term maintainance issues
Use of if-else-statements in "Abstract Factory" implementation is prohibited -- for obvious reasons of long term maintainance issues
So tell me if you have any other method/way/suggestion to do same thing in "Abstract Factory" with above conditions.
Mahadevan - could you please take another look at our display name policy and then edit your display name to include a first and last name? Not an abbreviation and/or name of a company or organization. Thanks.
"I'm not back." - Bill Harding, Twister
author and iconoclast
Originally posted by Mahadevan GSS: Definetely I used "Abstract Factory" pattern, but it is not a degenrate case . So tell me if you have any other method/way/suggestion to do same thing in "Abstract Factory" with above conditions.
First, it sounds like you had an emotional response to the word "degenerate", as if it were an insult. It's not -- I'm using the word in its mathematical sense of "multiple things collapsed into one."
In the "Factory Pattern", one "Factory" class could make different "Product" classes bases on some input parameter. Usually the creational method is a static method. Your list of objections above are mostly aimed at ways that the "Factory Pattern" can be implemented, and they are certainly valid objections. These objections are all addressed, actually, by the "Abstract Factory Pattern."
Despite the similar name, the "Abstract Factory Pattern" is a different pattern altogether. In that pattern, you define a "AbstractFactory" interface, often with many different "create" methods that create a family of "Product" classes. Then different implementations of the AbstractFactory create different implementations of the Product classes. The classic example of Product families are GUI widgets: you might have an AWTFactoryImple, a SwingFactoryImpl, and an SWTFactoryImpl. The createButton() method in AbstractFactory would be implemented to create a java.awt.Button in the AWTFactoryImpl, a JButton in the SwingFactoryImpl, etc. Similarly, the same AbstractFactory could have a createList(), createComboBox(), and other methods.
So I called your implementation "degenerate" because the AbstractFactory and the Product are the same class, and because there is only one create() method -- not because it was bad or perverted in some way.
Can you show me the real example of usage of the clone() method? Or whats the reason for this method?
Suppose you have a method which returns a reference to a mutable object (let us call it A). If you do not want the caller to change A, and cannot make A immutable, then you should defensively copy A and return a reference to the copy of A. Cloning is one way of making that copy of A, with the caveat that the cloning is shallow, not deep.
SCJP 1.4, SCWCD 1.3, SCBCD 1.3
Joined: Sep 16, 2005
Originally posted by Roger Chung-Wee:
Cloning is one way of making that copy of A, with the caveat that the cloning is shallow, not deep.
I'm not sure "cloning => shallow". The javadoc for Object.clone states (my emphasis): By convention, the object returned by this method should be independent of this object (which is being cloned). To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clone before returning it. Typically, this means copying any mutable objects that comprise the internal "deep structure" of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.
Joined: Jan 30, 2000
I'd say that the default implementation of clone() inherited from Object does give you a shallow clone. If you override it, you can get a deep clone - or something in between.
this is precisely why I do not make clone public. clone has an implementation that people expect when they see the method. shallow copy. But the contract says it does not have to be shallow. So when folks see clone rightfully they don't exactly know what to expect in return. and its not helpful if everyone returns something different from a standard method IMHO.
I always do something like so
[ March 24, 2006: Message edited by: Mr. C Lamont Gilbert ]
Clone gives you a copy of an object at a point in time. You might use it if you want a copy you can modify without affecting the original, or one that will remain unchanged even if another thread modifies the original.
We also recently discussed with the Prototype pattern.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: May 10, 2006
Thanks, thought it might be the case that it ensured the original copy was not being altered. I can imagine this being useful in arrays particularly.