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.
Related
I have an interface with 6 methods used to manage datasets. The only method that differs between implementations is getSerializedVersion() and the constructor that is able to parse the serialization string.
public interface DataSets {
public void addEntry(...);
public void removeEntry(...);
public void manipulateEntry(...);
public SomeType getEntry(...);
public List<SomeType> getAllEntries();
// This differs:
public String getSerializedVersion()
}
I can't change the Interface.
My first idea was to generate an abstract class and implement the first five methods. For the concrete implementations (e.g. DataSetsXML, DataSetsYAML, ...) I only have to implement getSerializedVersion() and the constructor that that is able to read the String and initialize the object.
To make it more testable a different design might be better (https://stackoverflow.com/a/7569581) but which one?
Answers might be subjective, but I think there are some general rules or a least (objective) advantages and disadvantages of the different approaches,...
From what you explain the difference is something that is not related to the behavior of the class but just how it is serialized and unserialized. What I mean is that the DataSetsXML and DataSetsYAML would have the same identical funcionality but they would be serialized into different formats.
This means that there is no benefit in keeping getSerializedVersion() coupled with the DataSets class. You should totally decouple them.
You could have a serialization interface sort of:
interface DataSetsSerializer
{
public DataSets unserialize(String string);
public String serialize(DataSets sets);
}
and then take care of differente implementations just in this class, eg:
class YAMLDataSetsSerializer implements DataSetsSerializer
{
public DataSets unserialize(String string) {
DataSets sets = new DataSets();
...
}
public String serialize(DataSets sets) {
...
}
}
By elaborating on JB Nizet comment, if you have to keep a DataSetsSerializer inside a DataSets instance (which IMHO makes no sense since they should be decoupled in any case, as a specific way of serialization shouldn't be bound to the data to be serialized) then the approach would be the following:
class DataSets {
final private DataSetsSerializer serializer;
public DataSets(DataSetsSerializer serializer, String data) {
this.serializer = serializer;
serializer.unserialize(this, data);
}
#Override
public String getSerializedVersion() {
return serializer.serialize(this);
}
}
This requires a slight change in the proposed interface and it's not a clever design but it respects your requirements.
I think it is reasonable to use an abstract class. You can test the concrete implementations of the abstract class (which indirectly tests the abstract class as well).
I have gone through http://www.dofactory.com/net/design-patterns in trying to find out the most efficient to create a design pattern in which "one visible class utilizes many hidden classes" to create a fluent API. Below is the code I currently have:
public class VisibleClass {
Private OrderClass order;
private ReceiptClass receipt;
public VisibleClass makeOrder() {
if (!(order instanceof OrderClass))
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (!(receipt instanceof ReceiptClass))
receipt = new ReceiptClass();
receipt.print();
return this;
}
}
class OrderClass implements IOrder {
public void make() {}
}
class ReceiptClass implements IReceipt {
public void print() {}
}
interface IOrder { void make(); }
interface IReceipt { void print(); }
Here is how I am currently using the API:
public static void main(String[] args) {
VisibleClass x = new VisibleClass();
x.makeOrder().printReceipt();
}
It this a good approach? Can a better approach be used for it?
*EDIT: Also, I should add that the VisibleClass will implement all methods of the hidden classes.
Your approach is quite good. Here some recommendations:
1 Change class member types to their interfaces as for 'Program to an interface, not an implementation' principle:
public class VisibleClass {
private IOrder order;
private IReceipt receipt;
2 Do you really need to check class types in makeOrder and printReceipt methods ? Creating instances after null check seems enough:
public VisibleClass makeOrder() {
if (null == order)
order = new OrderClass();
order.make();
return this;
}
public VisibleClass printReceipt() {
if (null == receipt)
receipt = new ReceiptClass();
receipt.print();
return this;
}
3 This approach is valid until methods of VisibleClass will be called by a single thread. If you're going to place it in a multi-thread program, you should ensure that there are only one instances of OrderClass and ReceiptClass each. There are 3 ways you can follow:
a. Create instaces of OrderClass and ReceiptClass in constructor and make VisibleClass singleton.
b. Make OrderClass and ReceiptClass singleton and remove new lines.
c. Create instances surrounded with synchronized block in makeOrder and printReceipt methods.
one visible class utilizes many hidden classes
don't do that with business classes. Fluent syntax's is great for configuration etc, but not for plain business code.
The reason is that the class itself losses control over it's state which can put it in an inconsistent state (i.e generate faulty results).
There is even a principle called Law of Demeter which is about just that.
If you have a business requirement that a receipt should be printed on a new order you should just return it as a return value.
var receipt = visibleClass.makeOrder();
As for using interfaces for entity/business classes, why do you do that? why would you want to abstract away those? The usually do not have any other dependencies or different types of implementations.
You can try using the Facade Design pattern
Or may be try using a Decorator Pattern
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.
Code 1:
public class User1 implements MyInterface
{
#Override
public void doCalculation() { }
}
public class User2 implements MyInterface
{
#Override
public void doCalculation() { }
}
interface MyInterface
{
public void doCalculation();
}
Code 2:
public class User1
{
public void doCalculation() { }
}
public class User2
{
public void doCalculation() { }
}
Here in my Code 1 I have MyInterface which has an empty method doCalculation().
That doCalculation() is used by user1 and user2 by implementing MyInterface.
Where as in my Code 2 I have two different classes with defined doCalculation() method.
In both the cases code1 and code2 I myself have to write the implementation. My method doCalculation() is just an empty method.
So what is the use of MyInterface here?
It only provides me the method name or skeleton (is that the only advantage of interface)?
Or else would I save any memory while using MyInterface?
Is that, it only provides the empty method for an class which implements it, then why not I define it by myself as I have done in my code2.
More than that is there any more advantage on using an interface.
Interfaces are used a lot because they are basically a blueprint of what your class should be able to do.
For example, if you are writing a video game with characters, you can have an interface that holds all the methods that a character should have.
For example
public interface Character {
public void doAction();
}
And you have 2 characters, for example an ally and an enemy.
public class Ally implements Character {
public void doAction() {
System.out.println("Defend");
}
}
public class Enemy implements Character {
public void doAction() {
System.out.println("Attack");
}
}
As you can see, both classes implement the interface, but they have different actions.
Now you can create a character which implements your interface and have it perform its action. Depending on if it's an enemy or an ally, it'll perform a different action.
public Character ally = new Ally();
public Character enemy = new Enemy();
And in your main program, you can create a method that accepts any object that implements your interface and have it perform it's action without knowing what kind of character it is.
void characterDoAction(Character char) {
char.doAction();
}
If you would give ally to this method, the output would be:
Defend
If you would give enemy to this method, the output would be:
Attack
I hope this was a good enough example to help you understand the benefits of using interfaces.
There are a lot of advantages of interface driven programming.
What does "program to interfaces, not implementations" mean?
Basically you are defining a contract in an interface and all the classes which implement the interface have to abide by the contract.
Answers to your queries:
1.It only provides me the method name or skeleton (is that the only advantage of interface)?
--> Its not just about providing the method name but also defining what the class implementing the interface can do.
2.Or else would I save any memory while using MyInterface?
--> Nothing to do with the memory
Is that, it only provides the empty method for an class which implements it, then why not I define it by myself as I have done in my code2.
--> see the advantages of interface driven programming.
4.More than that is there any more advantage on using an interface.
--> Plenty,specially dependency injection , mocking , unit testing etc.
A very good explanation can be found here when-best-to-use-an-interface-in-java. It really depends on what you're building and how much scalability, code duplications, etc you want/don't want to have.
Many classes use interfaces to perform some function, relying on other programmers to implement that interface respecting the contract that an interface govern. Such classes are, for example, KeyListeners, MouseListeners, Runnable, etc.
For example: JVM knows what to do with a Thread, how to start it, stop it, manipulate it, but it does not know what your Thread should do, so you have to implement the Runnable interface.
Interfaces offer you a level of abstraction which can be leveraged in other classes. For example, if you have an interface called GemetricFigure, in a class that prints girth of a GeometricFigure you could iterate over a list of all GeometricFigures like:
public class Canvas {
private List<GeometricFigure> figures;
public void print() {
for (GeometricFigure figure : figure) {
System.out.println(figure.getGirth());
}
}
}
And if the GeometricFigure has only that method:
public interface GeometricFigure {
public Double getGirth();
}
You wouldn't care how Square or Circle implement that interface. Otherwise, if there were no interface, you could not have a list of GeometricFigures in Canvas, but a list for every figure type.
With the interface approach you can do the following:
List<MyInterface> list = new ArrayList<MyInterface();
list.add(new User1());
list.add(new User2());
for(MyInterface myInterface : list) {
myInterface.doClaculation()
}
This does not work with the second approach. Interfaces are for the code that use your classes - not for your classes themselves.
You can use interfaces in many cases. Also the situation you describes: You needn't to know, which implementation you have.
For example you have anywhere in your code a method, that returns the current singed in user even you don't know if it is User1 or User2 implementation, however that both of them can calculate something by method doCalculation. I add a really dummy example of that situation:
public void dummyExampleCalculation() {
getCurrentUser().doCalculation();
}
public MyInterface getCurrentUser() {
if(...) {
return new User1();
} else {
return new User2();
}
}
That is what Object Oriented Programming is all about.Interfaces are used to perform polymorphism. You said, you can implementations in code2 for both the classes, what if in future there is user3 who needs to doCalculation. You can just implement that interface and write your calculation in your own form.
When you want to provide a basic functionality to all your users abstract classes comes into picture where in you can declare an abstract method do calculation and provide implementation of that basic functionalities which then each user will extend and can doCalculation in their own way.
Interface is like a contract that your implementing class should satisfy. Usually, you will write an interface and make all your other class's implement it with their own implementation.
Example:
interface IExporter {
public void export();
}
public class PDFExport implements IExporter {
public void export(){
//code for PDF Exporting
}
}
public class XLSExport implements IExporter {
public void export(){
//code for XLS Exporting
}
}
public class DOCExport implements IExporter {
public void export(){
//code for DOC Exporting
}
}
Interface in Java is used to impose an implementation rule on classes. That means you can declare the signature of functions in interfaces and then implement these function in various classes by exactly following the function signature.
You can see a clear and realistic example on the following webpage
http://www.csnotes32.com/2014/10/interface-in-java.html
I like to realize the following scenario. (example)
I have 3 Classes:
Controller
Apple
Car
public class Apple implements IBonus {
public String name;
public String weight;
}
public class Car implements IBonus{
public String brand;
public String vmax;
public String power;
}
public class Controller {
public List<String> values;
public void doWork(IBonus bonusObject){
if(bonusObject instanceOf Car){
Car c = (Car)bonusObject;
values.add(c.brand);
values.add(c.vmax);
values.add(c.power);
}
if(bonusObject instanceOf Apple){
Apple a = (Apple)bonusObject;
values.add(a.name);
values.add(a.weight);
}
}
}
Now, I have a lot of Classes like apple and car. And there is also the possibility that some variables of each class will be changed, added or removed in the near future.
This will mean that I always have to adjust the code in the controller class.
Does anyone know a suitable pattern?
You don't need any pattern for this. Just plain old polymorphism:
public interface IBonus {
void fillStringList(List<String> values);
}
...
public void doWork(IBonus bonusObject){
bonusObject.fillStringList(values);
}
EDIT: Design pattern "Visitor".
Change your iBonus interface to add a method:
void add(List<String> values);
Have the Controller instead do
bonusObject.add(values);
This way you delegate the specific task (adding an object to 'values') to the specific implementation.
Basically whenever you find yourself writing code like the above (if instanceof or switch()) you should instead consider delegating the task to an abstract method.
You may want to consider "double dispatch" aka. "Visitor"
http://en.wikipedia.org/wiki/Visitor_pattern
The Wikipedia version is very generic, and splits out the "Visitor" logic (adding to the list) into a seperate class. In the below version the "Bonus" objects play that part, and the double dispatch structure is used instead.
In that scenario you have two interfaces: One for the bonus object, and one for the controller. The bonus object has a method called
void visit(Controller c);
The controller will then invoke the bonus object thus:
bonusObjecv.visit(this);
The purpose of "Visitor" is largely to let you vary the implementations independant of each other. It is a more generic version of the simple, polymorphic solution. Instead of using a generic class such as List you use the Controller interface. That way you make the interaction between controller and visited object explicit.
You could add a method:
public List<String> getValues();
to your IBonus interface and just use the following in doWork:
values.addAll(bonusObject.getValues());
Each IBonus type will then need to implement how to create the list.
I think Factory pattern will suit in this condition.
Factory pattern Example