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.
Related
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.
Basically, I have a mutable object in Java and its state is both accessed and modified by several methods of a certain class. The data stored in the object is also used by another class, but the difference is that the second class should not be allowed to modify the data, just to use it.
In C++, I would normally just pass a const reference to the object at hand, but I realize that there is no direct equivalent in Java.
Just to clarify, the following code snippet shows what I have in mind:
public interface Figure
{
void onSizeChanged(SizeInfo info);
void draw();
}
public class FigureView extends View
{
private Figure figure;
private SizeInfo sizeInfo;
...
public void onResize()
{
//Modify the state of sizeInfo, then pass it to the figure.
figure.onSizeChanged(sizeInfo);
}
}
Let's say that SizeInfo is a large object, so I don't want to make a memberwise copy, but just pass it by reference. The code above succeeds in allowing any Figure to access the data of the SizeInfo object, but it also allows the Figure to modify the object. Errors caused by such behavior may be hard to track, so I want to pass an 'immutable reference' to the SizeInfo.
The best solution I have found so far is to create an non-static inner class of SizeInfo which only consists of getters:
public class SizeInfo
{
//These represent the large set of data inside the class.
private long foo;
private double bar;
private Export mExport = new Export();
//Setters (only available if you have a direct reference to SizeInfo):
public void incrementFoo()
{
foo++;
}
public void setBar(double bar)
{
this.bar = bar;
}
//SizeInfo getters:
public long getFoo()
{
return foo;
}
public double getBar()
{
return bar;
}
public double getBaz()
{
return bar * foo;
}
//A non-static inner class:
public class Export
{
public long getFoo() { return foo; }
public double getBar() { return bar; }
public double getBaz() { return bar * foo; }
}
public Export export() { return mExport; }
}
With this code, you only have to change the method signature in Figure from onSizeChanged(SizeInfo) to onSizeChanged(SizeInfo.Export) and pass sizeInfo.export() to the method instead of sizeInfo to make it work as expected. This is very easy to use from the client side, but the code redundancy caused by having to repeat each getter twice is definitely not elegant. The alternative of placing the getters only in SizeInfo.Export and replacing each sizeInfo.getBaz() with sizeInfo.export().getBaz() is even worse. That is why I am looking for a more elegant approach.
I realize that this particular example might not be believable in terms of SizeInfo being too big to just create a memberwise clone. However, there are countless other examples. For instance, if I had a mutable object representing the ARGB data of an image (perhaps due to the image being generated pixel by pixel with the use of some mathematical formulas), and then wanted to pass it to a method which should not be able to modify it, the problem would still appear.
You could create an interface, say SizeInfoView, which contains only the getters. Then SizeInfo would implement that interface, but add setters as well. Figure would only receive a reference to the SizeInfoView interface. The caller can of course still downcast to a SizeInfo, but you'd have the same issue in C++ with const_cast. It's usually good enough to prevent accidents.
Bear in mind, though, that you're getting an unmodifiable object, not an immutable object. The difference is that somebody else could modify it, and the changes would be reflected in the unmodifyable view. But again, the same is true for C++ const references.
Create a ReadOnlySizeInfo interface containing the getters, make SizeInfo implement that interface, and pass the interface instead of SizeInfo to onSizeChanged().
You will still pass a mutable object, but the Figure doesn't know about it: all it knows about what it receives is that it's a ReadOnlySizeInfo. It could still cast and mutate the object, but that wouldn't be a bug anymore: it would be an evil behavior.
The compiler does not let a static method call a non static method. I understand it does this because a not static method usually ends up using an instance variable.
But does it make sense to have a non static method which does not use an instance variable. If we have a behavior which does not affect or isn't affected by the instance state , shouldn't such a method be marked as static.
Well sure! Let's assume that you have in interface IMyCollection. It has a method boolean isMutable().
Now you have two classes, class MyMutableList and class MyImmutableList, which both implement IMyCollection. Each of them would override the instance method isMutable(), with MyMutableList simply returning true and MyImmutableList returning false.
isMutable() in both classes is an instance method that (1) does not use instance variables, and (2) does not affect instance state. However, due to constraints in the language (it's impossible to override static methods), this design is the only practical one.
Also, I would like to clear up a misconception (as #manouti did as well): non-static methods aren't instance because they use any instance variables or affect instance state; they're instance methods because they were defined that way (without the static keyword), and thus have an implicit this parameter (which, in languages like Python, is actually explicit!).
Often times, no. If the method doesn't touch any instance state, there's no reason to tie it to an instance.
Of course, static methods can't be inherited or overridden, so that's one obvious time that you would want to have an instance method that doesn't use instance state. The strategy pattern is a classic example of this.
Another case where you may tie it to an instance anyway is if this is a public API and you imagine that you may want to tie the method to instance state in the future. In that case, backwards compatibility concerns for people who are using your API may make it difficult (or impossible) to turn that static method into an instance method.
Because static methods cannot be overridden, many developers that are concerned about testability of their code try to avoid static methods in Java altogether.
Code is more testable if dependencies can be replaced with mock objects. Mockito and EasyMock are the most common tools to help with this, and they rely on inheritance to create subclasses that allow you to easily override the (often complex) method that you don't want to test ... so that your test is focused on what you do want to test.
I don't go to the extreme of trying for zero static methods, but when I concede to include them, I often regret it later, for testing reasons.
All of this is very frustrating, because it has nothing to do with what ought to be the design consideration of static vs instance methods. Which makes me wish for those languages that allow you have have functions that aren't connected with a class ...
If one were writing a human-readable description of the method's purpose, would it make mention of an object? If so, use an instance method. If not, use a static method. Note that some methods might be described either way, in which case one should use judgment about which meaning is better.
Consider, for example, "Get the address to which a Freedonian income tax form should be mailed" vs "Get the address to which Freedonian income tax forms should be mailed"? The first question should be answered by an instance method; the second by a static method. It may be that Freedonia presently requires all tax forms to be sent to the same address (in which case the former method might ignore all instance fields), but in future may have different offices for people in different regions (in which case the former method might look at the taxpayer ID and select a mailing address based upon that, while the latter method would have to direct forms to an office which could accept forms for anyone and redirect them as needed).
I understand it does this because a not static method usually ends up using an instance variable.
Even if the instance method does not use an instance variable, it is still bound to the instance of the class. In fact, it has a reference to this implicitly in the method arguments.
In other words, in the following method:
public void foo() {
}
this is implicitly passed as the first local variable in the method.
EDIT:
Re-reading the question, it's more of a broad question that depends on the situation. Generally if the method does not need the instance (and you're pretty sure it won't), then just make it static.
A nice example is an object-oriented encoding of booleans. Most languages, even object-oriented ones like Java, opt for an Abstract-Data-Type-oriented encoding of booleans, but e.g. Smalltalk uses an OO encoding, and almost none of the methods make use of any instance state. It looks a bit like this:
import java.util.function.Supplier;
#FunctionalInterface interface Block { void call(); }
interface Bool {
Bool not();
Bool and(Bool other);
Bool or(Bool other);
<T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch);
void ifThenElse(Block thenBranch, Block elseBranch);
static final Bool T = new TrueClass();
static final Bool F = new FalseClass();
class TrueClass implements Bool {
public Bool not() { return F; }
public Bool and(Bool other) { return other; }
public Bool or(Bool other) { return this; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return thenBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
thenBranch.call();
}
}
class FalseClass implements Bool {
public Bool not() { return T; }
public Bool and(Bool other) { return this; }
public Bool or(Bool other) { return other; }
public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
return elseBranch.get();
}
public void ifThenElse(Block thenBranch, Block elseBranch) {
elseBranch.call();
}
}
}
public class Main {
public static void main(String... args) {
Bool.F.ifThenElse(() -> System.out.println("True"), () -> System.out.println("False"));
// False
}
}
In fact, if you follow a serious commitment to OO, use a lot of referentially transparent methods, and favor polymorphism over conditionals, you will often end up with methods in lots of subclasses, where each implementation in one of the classes returns a constant value.
I think sometimes it is yes,because non static method can override to do different tasks for different class,but the task may not involve instance variable,e.g.:
Fruit.java
public class Fruit{
public void printInfo(){
System.out.println("This is fruit");
}
}
Orange.java
public class Orange extends Fruit{
public void printInfo(){
System.out.println("This is orange");
}
}
Grape.java
public class Grape extends Fruit{
public void printInfo(){
System.out.println("This is grape");
}
}
print info of object:
Fruit f=new Grape();
f.printInfo();
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.
There is a part in my java code where I am extending a class from a library which I haven't written.
#override
public Object getPropertyValue(Object id) {
if(id.equals(model.PROPERTY_RENAME))
model.setName((String)value);
else if(id.equals(model.PROPERTY_COLOUR))
model.setColor((Color)value);
}
Now in this case how should I modify this code to make it scalable. There would be many more properties like location, dimension, etc. Now this model is instance of an abstract class AbsModel.
So every class implementing the AbsModel would have different properties. So the class architecture should be there, so that this part of code remains unchanged, no matter how many more model classes I add.
It looks like you want to carry out some operation on the model when this method (getPropertyValue) is called. I would create a Map of id onto the interface ModelOperation defined as follows:
public interface ModelOperation {
void operate(Object value);
}
Then the map would be defines as follows:
map.put(model.PROPERTY_RENAME, new RenameOperation(model));
Your extension class would then look like this:
#Override
public Object getPropertyValue(Object id) {
map.get(id).operate(model);
// etc...
}
For example, RenameOperation would be defined like this:
public class RenameOperation implements ModelOperation {
public RenameOperation(Model model) {
// etc...
}
public void operate(Object value) {
model.setName((String)value);
}
}
This allows you to support as many model operations as you like and means you don't have to change the extension class you have to write. The above is just an outline. You could use generics on the ModelOperation implementations to avoid the cast of the value in each one.
I guess reflection is probably the answer here if you can rely on some naming to help direct you.
It's not going to be nice, but the idea would be that you'd have a method that would reflect on the type and look up the appropriate method. The code belwo
public Object setPropertyValue(Object id) {
String className = id.getClass().getSimpleName();
// Hope that the method is called set<CLASS> and takes a single parameter that is the class
Method method = model.class.getMethod("set" + className, id.getClass());
// Invoke the method (TODO deal with all of the exceptions)
method.invoke(model, id);
}
There are multiple ways of doing this -- though it depends on what do you mean by "scalable" (being able to cope with lots of requests per second or being able to cope with lots of properties?):
one way -- if you're going to go down the path you have outlined in your code is to have those properties that are used very often at the top of your if/then/else block -- so their execution path is very short. this would "scale up" well for lots of requests as not too much time is being spent in actually executing the method (in most cases at least!)
another way -- and this scales up well for lots of properties and easiness of maintaining the code but you will take a hit on execution time: have a Map that maps property names to setxxx() method names, then you can use reflection to invoke these methods on the target object (id in your case) on each call. Classes extended your class will only have to provide a getMap() method which will return the mapping name-to-setter method, which can be a static member and initialized on class load.
Store your properties in a Map -- in which case setName() is the same as map.put( PROPERTY_RENAME, value)
Since in Java functions are not first class citizens, the "nice" route would be very awkward: define an enum with one value per each constant above (i.e. for each property), and a virtual method e.g. update(Object value, then override the method in each enum to update the corresponding property. If you can, redefine the constants PROPERTY_RENAME etc. themselves as enums. This still results in code bloat.
The other way is to use reflection. If you can use the same ids as the property names you want to update, you only need to invoke the setter for the property (as illustrated in other answers). Otherwise you may need to introduce a mapping from ids to property names.
A version not using reflection, call the base class's implementation:
public Object getValue(Object id) {
Object ret = super.getValue(id);
if (ret == null) {
// Subclass specific properties
}
return ret;
}
A common way around this is to use reflection like
public Object getValue(IdType id) {
Method getter = model.getClass().getMethod("get" + id);
return getter.invoke(model); // throws Exceptions.
}
OR
public void setValue(IdType id, Object value) {
Method setter = model.getClass().getMethod("set" + id, value.getClass());
setter.invoke(model, value); // throws Exceptions.
}
I solved this issue by creating an interface. So the code is.
public interface IModel
{
public void setProperty(String propertyName);
}
Rest of the classes were
public class HelloModel implements IModel
{
public void setProperty(String propertyName)
{ code for handling the properties goes here ... }
}
So in this case every class has to handle it's own property setters.
Is this the best way to handle abstraction ? I think this model is very scalable ...