Getters in Java -- is what I'm doing safe? - java

I have a private inner class that encapsulates some functionality. It populates two ArrayLists. I have getters for the ArrayLists that just return the private variable. Are the getters needed? Can I just make the ArrayLists public instance variables? What's the best practice?
public class OuterClass {
//Stuff the OuterClass does
private class InnerClass {
private ArrayList<String> array1;
private ArrayList<String> array2;
public InnerClass() {
//Init and do stuff w/ arrays
}
public ArrayList<String> getArray1() {
return array1;
}
public ArrayList<String> getArray2() {
return array2;
}
}
}

Yes can make the Arraylist public, although best practice is to use getters. This allows you to build in side effects such as
perform computation
check constraints
lazy initialization
provide methods for possible inheritance
It also lets you modify the internals of your class in the future without breaking the contract.

Best practice is to supply getters. This avoids somebody setting the lists themselves, isolates users from underlying code changes, etc.
Whether or not they should be an unmodifiable list is a separate issue, and just depends.

The reason you wouldn't make the variables public is because you want to hide the implementation. What happens if you switch from an ArrayList to an actual array down the road? All your code would break. So you write to interfaces.
You may also want to avoid returning references to the array anyway, and rather provide methods to modify the array in ways that make sense for the class. Otherwise, it's possible for those using your class to make modifications that aren't expected by your class.
For instance:
Foo foo = new Foo();
List list = foo.getArray();
list.add( new Object() );
At this point, an object has been added to the content of your Foo object, and your foo object didn't get any chance to check the validity of that addition, to deny the addition, or to otherwise know it's there. If you had decided for performance reasons to delay creation of the array, you'd have been accessing a null. Boom.

Best practice is to neither supply getters nor setters, instead your objects should not expose their implementation details.
Standard Java practice is to have private data members (a.k.a. fields) and to provide getters and setters.

Assuming that the outer class (inside which the inner class is defined) isn't huge (like K lines of code) there's no point in defining getters.
Rationale:
The inner class is private. Getters will allow you to make (very limited) changes to the inner class without affecting the outer class. If the outer class is sufficiently small then the scope of code that is affected by changes that getters can prevent from leaking is also very small. Thus, there's no point in introducing them a-priori. If the need comes - introduce them, but till then - just stick with the simpler code.
Of course, if you'r refactoring the code and changing the inner class into a (standalone) top level class, then you need to introduce getters (or - even better - change the design to a tell-don't-ask scheme)

It's preferable to expose your API via Getters/Setters for encapsulation purposes, it's also good practice to declare your objects by interface types.
private List<E> list; // = new ArrayList<E>(); or initialize elsewhere
public List<E> getList() {
return list;
}
public void setList(List<E> list) {
this.list = list;
}

Here is an approach that keeps the client from mucking about with the ArrayLists you provide through the getters. Note that the attempt to modify the ArrayList via the reference returned by the getter getResultsArray() is supposed to raise an exception:
package testCode;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
public class TestClass {
private ArrayList<String> resultsArray = Lists.newArrayList();
public void calculateResults(){
resultsArray.add("1");
resultsArray.add("2");
resultsArray.add("3");
}
public List<String> getResultsArray() {
return new ImmutableList.Builder<String>().addAll(resultsArray).build();
}
}
And a test driver:
package testCode;
public class TestMain {
public static void main(String[] args) {
TestClass testClass = new TestClass();
testClass.calculateResults();
for (String result : testClass.getResultsArray()) {
System.out.println(result);
}
try {
testClass.getResultsArray().add("fake result");
} catch (Exception e) {
System.out.println(e);
}
}
}
And the output:
1
2
3
java.lang.UnsupportedOperationException
The ImmutableList comes from Google's Guava library. In this case, an ImmutableList implements the List interface, but any method that would change the list immediately throws an UnsupportedOperationException. Note that because the ImmutableList can never change, the implemented code is very small, since anything in a normal List implementation that adjusts the list simply doesn't get written here. Very useful, and in this case, I am using it to implement defensive programming to prevent users of my TestClass from adjusting the test results I've returned to them.

Related

Method Caller and Callee, circular class level method invocations

What are the problems with doing method caller and Callee of two different classes doing circular class level different method calls. You pass "this" reference, as a parameter to some other class instance method and the Callee doing further method invitation on caller which is passed as parameter.
One reason for doing that, In a factory class, Different implementations needs different kinds of data, so you put the data that is needed as multiple contracts/interface methods and have your caller implement them. If you have just one class it is easier to implement encapsulation, But different classes require different sets of data.
Following is simple example of such, Here StudentService calls MathClassScorer's topscorer method which in turn calls StudentService's getStudentList method. In a complex scenario, you might be calling multiple methods of parent caller.
public interface IStudentData {
public List<Student> getStudentList();
}
public class StudentService implements IStudentData {
private List<Student> studentList;
public String getTop() {
// Factory returns MathClassScorer
IScore scorer = ClassScorerFactory.get();
return scorer.topscorer(someOtherData, this);
}
#Override
public getStudentList() {
// do something and return studentList;
return studentList;
}
}
// IScore contains topscorer method
public class MathClassScorer implements IScore {
#Override
public String topscorer(Map someOtherData, IStudentData data) {
List<Student> studentList = data.getStudentList();
//do something before and after
return SOMETHING_AFTER
}
}
The Question is, Is there problem in the above approach ?
Well, the whole topic of OO is a bit controversial I'm afraid. But in my opinion the problems with the above code start with the naming of your classes. IStudentData is not an object. Holding some data is not a responsibility, and objects need responsibilities.
Then the design requires that the IScore objects know about the internal data content of the IStudentData, disregarding the object completely. The code also suggests that the IScore needs to know about the internal workings of Student too.
A good OO design is where objects actually have responsibilities, and their data is visible as little as possible, ideally not at all.
So, without knowing all the details, here is what your objects could look like:
public class Student {
public boolean isBetterAtMathThan(Student other) {
...
}
}
public class Students { // or StudentRepository
public Student getBestStudentAtMath() {
return students.stream().max(toComparator(Student::isBetterAtMathThan)).get();
}
}
Or, if you really want to generalize over a couple of different comparable skills, then you still can do that without exposing the data from Students:
public class Students {
public Student getBestStudentAt(Comparator<Student> skillComparator) {
return students.stream().max(skillComparator).get();
}
}
The point is, the Student should not expose data, but offer operations, or create other objects that can do stuff. Similarly, Students (the Service in your code) should not expose a list of students, instead it should provide methods to actually do stuff.
There are no problems with doing that. It is a common practice, known as the Strategy pattern.
Using injection like that is a very useful technique for decoupling logic, allowing unit testing of each component, by supplying mock objects.

Combine advantages of clone and reference?

In Java, and maybe also in other languages, for example in a getter you have to decide if you want to return a reference to something or a clone (copy).
return myInstance;
Just returning the reference is very fast and needs no additional memory but modifications of an instance get "written back" the the original one.
return myInstance.clone();
Returning a clone needs time and doubles the memory for that variable but keeps it safe.
It is possible to create an immutable view on something:
return MyUtil.immutableView(myInstance);
but then sometimes I want to modify it, just not to have it written back.
Now my idea is, is it possible (or already done, or is there a programming language that does it) to create an object that is initially a reference to something as long as there are no modifications. As soon as the first modification begins, the reference would update itself to a clone.
Something like this:
Class<T> CloneReference
{
T ref;
boolean cloned=false;
public CloneReference(T ref) {this.ref=ref;}
T getForReadOnly()
{
return ref;
}
T getForReadWrite()
{
if(!cloned) ref=ref.clone();
return ref;
}
}
Unfortunately, this solution is complicated, clumsy and easy to break (calling getForReadOnly() and then using instance changing operations). Is it possible to do better or is that just not possible with Java?
What you're looking for sounds pretty much like Copy-On-Write. I remember that PHP is a language which did implement this.
I think it should basically be possible to implement COW in Java as well. I think of returning some proxy which is initialized with the original instance. On the first write access the proxy will continue using a copy. Here's a SSCCE:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.junit.Test;
import static org.junit.Assert.*;
public class CowSSCCE {
public interface Bean {
public String getName();
public void setName(String name);
public Object clone();
}
public class BeanImpl implements Bean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() {
BeanImpl copy = new BeanImpl();
copy.name = new String(name);
return copy;
}
}
public class COWInvocationHandler implements InvocationHandler {
private Bean instance;
private boolean copy = false;
public COWInvocationHandler(Bean instance) {
this.instance = instance;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// copy only on the first setter call.
if (!copy && method.getName().startsWith("set")) {
instance = (Bean) instance.clone();
copy = true;
}
return method.invoke(instance, args);
}
}
#Test
public void testCOW() {
Bean original = new BeanImpl();
original.setName("original");
Bean reference = (Bean) Proxy.newProxyInstance(
Bean.class.getClassLoader(), new Class[] { Bean.class },
new COWInvocationHandler(original));
// no write access, reference is pointing to the original instance
assertEquals(original.getName(), reference.getName());
assertEquals(original.toString(), reference.toString());
// write access, reference is a copied instance
reference.setName("reference");
assertEquals("reference", reference.getName());
assertNotEquals(original.getName(), reference.getName());
assertNotEquals(original.toString(), reference.toString());
}
}
As someone mentioned readability, this shouldn't be an issue: Write an advice for e.g. the annotation #ReturnCopyOnwriteReference which replaces transparently the returned object with the proxy. An API method which returns such a proxy needs only that annotation:
#ReturnCopyOnwriteReference
public Bean getExpensiveBean() {
return originalBean;
}
If you're just looking for a COW collection use Java's CopyOnWriteArrayList.
Look at Scala programming language. It runs in JVM, and variables in most cases are immutable.
In Java there is a java.util.Collections#unmodifiableCollection() method, which wraps any collection into unmodifiable collection. This prevents it from editing. But I did not saw or think of any use case which would provide your desired behavior.
It sounds like you want something like C++'s const correctness. Unfortunately, there's nothing so innate in Java, but there are several strategies for achieving a similar result.
The whole point of any of these is to insure program correctness, and helping to reduce side effects.
Copy constructor
Always return a copy, that way the object inside the class is safe from modification. Implementing a copy constructor is probably the easiest, but you probably want a deep copy, which means any non-primitive members need to provide a way to obtain a deep copy of themselves (like another copy constructor).
Unmodifiable views
Java's Collections class does this with Collections.unmodifiableList, etc. This method accepts a List and proxies it with it's own (private) List implementation that forwards calls to accessor methods, but mutator methods throw an UnsupportedOpperationException. This is a little more dangerous because you can only support this with documentation.
Class hierarchy
You could always have a top level interface Foo which is unmodifiable, and an interface ModifiableFoo, where necessary you only return the former. Probably the best option since you can enforce mutability with the compiler and not runtime exceptions, as above.
I wrote about this subject once in my blog:
http://eyalsch.wordpress.com/2010/02/11/refdamage/
In general, I try to follow the following principles, with respect to the "main" object and the reference that "escapes" from it (either as a parameter or a returned value):
1) If the main object exposes some reference, we must make sure that the reference can't be manipulated in such a way that the class is left in an inconsistent state. This can be done in many ways (defensive copies, immutability, listeners, etc..).
2) In case that modifications to the reference's state are legal and are automatically reflected in the main object state, this must be properly documented.
3) If the caller wishes to update the reference state without affecting the main object, it's the caller's responsibility to clone properly.

Singleton or static class?

I have the following class :
public class EnteredValues {
private HashMap<String, String> mEnteredValues;
public boolean change = false;
public boolean submit = false;
private static final EnteredValues instance = new EnteredValues();
// Singleton
private EnteredValues() {
mEnteredValues = new HashMap<String, String>();
}
public static EnteredValues getInstance() {
return instance;
}
public void addValue(String id, String value) {
if (mEnteredValues.put(id, value) != null) {
// A change has happened
change = true;
}
}
public String getValueForIdentifier(String identifier) {
return mEnteredValues.get(identifier);
}
public HashMap<String, String> getEnteredValues() {
return mEnteredValues;
}
public void clean() {
mEnteredValues.clear();
change = false;
submit = false;
}
}
This class is used to manage the values that a user has already entered, and the class should be accessible to all classes across the application.
When the activity changes I 'reset' the singleton by calling the clear method.
I chose the singleton pattern without really considering the option of a static class.
But now I was wondering if I shouldn't just use a static class..
What is the common way to handle a class that just manages values?
Is a static class faster as a singleton?
thx
The very fact that you are providing a clear method to reset the state of your Singleton dictates that you should not use Singleton. This is risky behavior as the state is global. This also means that unit testing is going to be a big pain.
One more thing. Never ever declare instance variables as public. Declare them as private or protected and provide getters and setters. Also, there is no need to initialize instance variables with a value that is their default value.
The main difference between a static class and the singleton pattern is that singleton may be used if you need to implement an interface or such. For this particular case I think you might be better off with a static class since you are not implementing any interface. Relating your question if its one faster to the other, I'd say is negligible the difference but using a static class will remove a small overhead of dynamic instantiation of the class.
What is bad in using singleton if you need such a design? If you need exactly one instance of some object designed to do specified things singleton is not a bad choice for sure.
#see Are Java static calls more or less expensive than non-static calls?
Read
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
From there:
Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.
Just for style
I prefer not to rely on Singleton if I don't need to. Why? Less cohesion. If it's a property you can set from outside, then you can test your Activity (or whatever) with unit testing. You can change your mind to use diferent instances if you like, and so on.
My humble advise is to have a property in each of your Activities (maybe you can define a common base class?), and set it at activity initialization with a new fresh instance.
Your code will not know nothing about how to get it (except the init code and maybe you can change it in the future).
But as I've said... just a matter of taste! :)

Simulate static abstract and dynamic linking on static method call in Java

Introduction
As a disclaimer, I'v read Why can't static methods be abstract in Java and, even if I respectfully disagree with the accepted answer about a "logical contradiction", I don't want any answer about the usefulness of static abstract just an answer to my question ;)
I have a class hierarchy representing some tables from a database. Each class inherits the Entity class which contains a lot of utility methods for accessing the database, creating queries, escaping characters, etc.
Each instance of a class is a row from the database.
The problem
Now, in order to factorize as much code as possible, I want to add information about related columns and table name for each class. These informations must be accessible without a class instance and will be used in Entity to build queries among other things.
The obvious way to store these data are static fields returned by static methods in each class. Problem is you can't force the class to implement these static methods and you can't do dynamic linking on static methods call in Java.
My Solutions
Use a HashMap, or any similar data structure, to hold the informations. Problem : if informations are missing error will be at runtime not compile time.
Use a parallel class hierarchy for the utility function where each corresponding class can be instantiated and dynamic linking used. Problem : code heavy, runtime error if the class don't exist
The question
How will you cope with the absence of abstract static and dynamic linking on abstract method ?
In a perfect world, the given solution should generate a compile error if the informations for a class are missing and data should be easily accessible from withing the Entity class.
The answer doesn't need to be in Java, C# is also ok and any insight on how to do this without some specific code in any language will be welcomed.
Just to be clear, I don't have any requirement at all besides simplicity. Nothing have to be static. I only want to retrieve table and columns name from Entity to build a query.
Some code
class Entity {
public static function afunction(Class clazz) { // this parameter is an option
// here I need to have access to table name of any children of Entity
}
}
class A extends Entity {
static String table = "a";
}
class B extends Entity {
static String table = "b";
}
You should use the Java annotation coupled with the javac annotation processor, as it's the most efficient solution. It's however a bit more complicated than the usual annotation paradigm.
This link shows you how you can implement an annotation processor that will be used at the compile time.
If I reuse your example, I'd go this way:
#Target(ElementType.TYPE)
#Retention(RetentionType.SOURCE)
#interface MetaData {
String table();
}
abstract class Entity {}
#MetaData(table="a")
class A extends Entity {}
#MetaData(table="b")
class B extends Entity {}
class EntityGetter {
public <E extends Entity> E getEntity(Class<E> type) {
MetaData metaData = type.getAnnotation(MetaData.class);
if (metaData == null) {
throw new Error("Should have been compiled with the preprocessor.");
// Yes, do throw an Error. It's a compile-time error, not a simple exceptional condition.
}
String table = metaData.table();
// do whatever you need.
}
}
In your annotation processing, you then should check whether the annotation is set, whether the values are correct, and make the compilation fail.
The complete documentation is available in the documentation for the package javax.annotation.processing.
Also, a few tutorials are available on the Internet if you search for "java annotation processing".
I will not go deeper in the subject as I never used the technology myself before.
I have run into the same problems as you, and am using the following approach now. Store Metadata about columns as annotations and parse them at runtime. Store this information in a map. If you really want compile time errors to appear, most IDEs (Eclipse e.g.) support custom builder types, that can validate the classes during build time.
You could also use the compile time annotation processing tool which comes with java, which can also be integrated into the IDE builds. Read into it and give it a try.
In Java the most similar approach to "static classes" are the static enums.
The enum elements are handed as static constants, so they can be accesed from any static context.
The enum can define one or more private constructors, accepting some intialization parameters (as it could be a table name, a set of columns, etc).
The enum class can define abstract methods, which must be implemented by the concrete elements, in order to compile.
public enum EntityMetadata {
TABLE_A("TableA", new String[]{"ID", "DESC"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("I'm positively TableA Metadata");
}
},
TABLE_B("TableB", new String[]{"ID", "AMOUNT", "CURRENCY"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("FOO BAR message, or whatever");
}
};
private String tableName;
private String[] columnNames;
private EntityMetadata(String aTableName, String[] someColumnNames) {
tableName=aTableName;
columnNames=someColumnNames;
}
public String getTableName() {
return tableName;
}
public String[] getColumnNames() {
return columnNames;
}
public abstract void doSomethingWeirdAndExclusive();
}
Then to access a concrete entity metadata this would be enough:
EntityMetadata.TABLE_B.doSomethingWeirdAndExclusive();
You could also reference them from an Entity implemetation, forcing each to refer an EntityMetadata element:
abstract class Entity {
public abstract EntityMetadata getMetadata();
}
class A extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_A;
}
}
class B extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_B;
}
}
IMO, this approach will be fast and light-weight.
The dark side of it is that if your enum type needs to be really complex, with lot of different params, or a few different complex overriden methods, the source code for the enum can become a little messy.
Mi idea, is to skip the tables stuff, and relate to the "There are not abstract static methods". Use "pseudo-abstract-static" methods.
First define an exception that will ocurr when an abstract static method is executed:
public class StaticAbstractCallException extends Exception {
StaticAbstractCallException (String strMessage){
super(strMessage);
}
public String toString(){
return "StaticAbstractCallException";
}
} // class
An "abstract" method means it will be overriden in subclasses, so you may want to define a base class, with static methods that are suppouse to be "abstract".
abstract class MyDynamicDevice {
public static void start() {
throw new StaticAbstractCallException("MyDynamicDevice.start()");
}
public static void doSomething() {
throw new StaticAbstractCallException("MyDynamicDevice.doSomething()");
}
public static void finish() {
throw new StaticAbstractCallException("MyDynamicDevice.finish()");
}
// other "abstract" static methods
} // class
...
And finally, define the subclasses that override the "pseudo-abstract" methods.
class myPrinterBrandDevice extends MyDynamicDevice {
public static void start() {
// override MyStaticLibrary.start()
}
/*
// ops, we forgot to override this method !!!
public static void doSomething() {
// ...
}
*/
public static void finish() {
// override MyStaticLibrary.finish()
}
// other abstract static methods
} // class
When the static myStringLibrary doSomething is called, an exception will be generated.
I do know of a solution providing all you want, but it's a huge hack I wouldn't want in my own code nowadays:
If Entity may be abstract, simply add your methods providing the meta data to that base class and declare them abstract.
Otherwise create an interface, with methods providing all your data like this
public interface EntityMetaData{
public String getTableName();
...
}
All subclasses of Entity would have to implement this interface though.
Now your problem is to call these methods from your static utility method, since you don't have an instance there. So you need to create an instance. Using Class.newInstance() is not feasable, since you'd need a nullary constructor, and there might be expensive initialization or initialization with side-effects happening in the constructor, you don't want to trigger.
The hack I propose is to use Objenesis to instantiate your Class. This library allows instatiating any class, without calling the constructor. There's no need for a nullary constructor either. They do this with some huge hacks internally, which are adapted for all major JVMs.
So your code would look like this:
public static function afunction(Class clazz) {
Objenesis objenesis = new ObjenesisStd();
ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz);
Entity entity = (Entity)instantiator.newInstance();
// use it
String tableName = entity.getTableName();
...
}
Obviously you should cache your instances using a Map<Class,Entity>, which reduces the runtime cost to practically nothing (a single lookup in your caching map).
I am using Objenesis in one project of my own, where it enabled me to create a beautiful, fluent API. That was such a big win for me, that I put up with this hack. So I can tell you, that it really works. I used my library in many environments with many different JVM versions.
But this is not good design! I advise against using such a hack, even if it works for now, it might stop in the next JVM. And then you'll have to pray for an update of Objenesis...
If I were you, I'd rethink my design leading to the whole requirement. Or give up compile time checking and use annotations.
Your requirement to have static method doesn't leave much space for clean solution. One of the possible ways is to mix static and dynamic, and lose some CPU for a price of saving on RAM:
class Entity {
private static final ConcurrentMap<Class, EntityMetadata> metadataMap = new ...;
Entity(EntityMetadata entityMetadata) {
metadataMap.putIfAbsent(getClass(), entityMetadata);
}
public static EntityMetadata getMetadata(Class clazz) {
return metadataMap.get(clazz);
}
}
The way I would like more would be to waste a reference but have it dynamic:
class Entity {
protected final EntityMetadata entityMetadata;
public Entity(EntityMetadata entityMetadata) {
this.entityMetadata=entityMetadata;
}
}
class A extends Entity {
static {
MetadataFactory.setMetadataFor(A.class, ...);
}
public A() {
super(MetadataFactory.getMetadataFor(A.class));
}
}
class MetadataFactory {
public static EntityMetadata getMetadataFor(Class clazz) {
return ...;
}
public static void setMetadataFor(Class clazz, EntityMetadata metadata) {
...;
}
}
You could get even get rid of EntityMetadata in Entity completely and leave it factory only. Yes, it would not force to provide it for each class in compile-time, but you can easily enforce that in the runtime. Compile-time errors are great but they aren't holy cows after all as you'd always get an error immediately if a class hasn't provided a relevant metadata part.
I would have abstracted away all meta data for the entities (table names, column names) to a service not known by the entities them selfs. Would be much cleaner than having that information inside the entities
MetaData md = metadataProvider.GetMetaData<T>();
String tableName = md.getTableName();
First, let me tell you I agree with you I would like to have a way to enforce static method to be present in classes.
As a solution you can "extend" compile time by using a custom ANT task that checks for the presence of such methods, and get error in compilation time. Of course it won't help you inside you IDE, but you can use a customizable static code analyzer like PMD and create a custom rule to check for the same thing.
And there you java compile (well, almost compile) and edit time error checking.
The dynamic linking emulation...well, this is harder. I'm not sure I understand what you mean. Can you write an example of what you expect to happen?

Java Decorating The Easy Way

Say you have an API that is not accessible to change:
List<LegacyObject> getImportantThingFromDatabase(Criteria c);
Imaging Legacy Object has a ton of fields and you want to extend it to make getting at certain information easier:
class ImprovedLegacyObject extends LegacyObject {
String getSomeFieldThatUsuallyRequiresIteratorsAndAllSortsOfCrap() {
//cool code that makes things easier goes here
}
}
However, you can't just cast to your ImprovedLegacyObject, even though the fields are all the same and you haven't changed any of the underlying code, you've only added to it so that code that uses LegacyObject still works, but new code is easier to write.
Is it possible to have some easy way to convert LegacyObject to ImprovedLegacyObject without recreating all of the fields, or accessors? It should be a fast opperation too, I konw you could perform something by using reflections to copy all properties, but I don't think that would be fast enough when doing so to masses of LegacyObjects
EDIT: Is there anything you could do with static methods? To decorate an existing object?
You would have to perform the copying yourself. You can either have a constructor that does this (called a copy constructor):
public ImprovedLegacyObject(LegacyObject legacyObject) {
...
//copy stuff over
this.someField = legacyObject.getSomeField();
this.anotherField = legacyObject.getAnotherField();
...
}
or you can have a static factory method that returns an ImprovedLegacyObject
public static ImprovedLegacyObject create(LegacyObject legacyObject) {
...
//copy stuff over
...
return improvedLegacyObject;
}
If you're planning on extending this behavior to other legacy objects, then you should create an interface
public interface CoolNewCodeInterface {
public String getSomeFieldThatUsuallyRequiresIteratorsAndAllSortsOfCrap() {
}
public String getSomeFieldInAReallyCoolWay() {
}
}
Then your ImprovedLegacyObject would look like this:
public ImprovedLegacyObject extends LegacyObject implements CoolNewCodeInterface {
//implement methods from interface
}
How about making a copy constructor for your Improved Legacy Object that takes a Legacy Object as an argument. Then just create new objects from the old ones.

Categories

Resources