"Leaking this" from a Design Standpoint - java

Warning: Leaking "this" in constructor
I keep running into this, and I have a nagging feeling that it's because my design is wrong or not optimal.
I understand that this warning is bringing to my attention the fact that I am allowing access to an object that is potentially not fully initialized.
Let's say that I need a Frame that HAS and requires a List (Frame(List list)). In List, I might want to do something such as add(). In order to make sure Frame knows as little about List as possible (only that it has one), I would want to access the containing Frame from the List (List HAS a Frame?). This seems a little silly, but I have 2+ implementations of List that will use Frame in different ways..
To ensure that my code is used properly, I would require a Frame in the constructor of List.
I would also require a List in the constructor of Frame, as it MUST have one:
public abstract class Frame {
private final List list;
public Frame(List list) {
this.list = list;
list.setFrame(this);
}
}
public abstract class List {
private Frame frame;
protected final void setFrame(Frame frame) {
this.frame = frame;
}
}
So, is this bad design, or should I really create some intermediate scaffolding that does this, or even leave the scaffolding to the user?
Thanks!

Introduce a factory method:
public static Frame createFrame(List list) {
Frame frame = new Frame(list);
list.setFrame(frame);
}
private Frame(List list) {
this.list = list;
}
This does not leak this, and always makes sure everything is configured correctly without the need for every caller to remember initializing both sides of the association.

I think that this sort of "doubly linked" structure, where a Frame points to a List that points back to its parent Frame, is something you ought to avoid unless you have a specific need for it. You should if possible try and make one of the two objects the "parent" that points to the "child."
It's a bit hard to understand at first why the double-linking is not such a great idea, but here are some reasons:
In a structure with clear parent-child relationships, it's trivial to reuse the same child objects in more than one parent. In a double-linked structure, on the other hand, if you want to create a new structure that shares some of the elements from an original, you either have to create new copies of the elements of interest, or you have to destroy the original structure.
There are many design patterns that rely on a clear chain of "command" in an object graph, and the double-linked structures obscure that chain of command from readers of the code.
A lot of the cases where processing of a child requires knowledge about the parent in which that child appears are better handled by passing the parent as a "context" argument to a method that processes the child. The classic example of this pattern is in interpreters, where evaluation of an expression takes as an argument an "environment" that contains all the of the outside information necessary to evaluate a child expression. (Or alternatively, you use a stateful Iterator or Hierarchical Visitor that navigates the structure and keeps track of location.)
This is not to say that the double-linked structures are never appropriate, but rather that the simpler, single-linked structures should probably be the first choice.

Related

Let callables/threads work on copy of an object in Java

I have a working code, in which I calculate the shortest path from every point (Dijkstra's algorithm) to every point in a graph.
But as soon as I want to use more than 1 thread with my ExecuterService, they all will work on the same graph for calculating the results, which of course makes the result unusable.
How can I make it so that one thread gets an own copy of the graph, so the callables run on that thread won't disturb the others? Is that even possible?
As Keqiang Li commented, you need to define a mechanism for copying the single graph data structure you already have. However, since you obviously need to first build the structure itself before creating multiple copies of it, one commonly-used trick is to use a builder pattern in order to create immutable objects on which you will actually do the search. Note that this needn't be implemented in an actual separate e.g. GraphBuilder class but rather you can simply implement a mechanism for creating immutable copies of a single mutable graph structure which you initially build incrementally while reading in your data:
public class MutableDirectedGraph implements DirectedGraph {
public MutableDirectedGraph() {
...
}
public Edge addEdge(final Node start, final Node end, final String label, final double weight) {
...
}
public Node addNode() {
...
}
...
}
public class ImmutableDirectedGraph implements DirectedGraph {
public ImmutableDirectedGraph(final DirectedGraph copyee) {
...
}
...
}
One nice thing about this approach is that you can implement MutableDirectedGraph to be easy to modify/build in an incremental fashion and then implement ImmutableDirectedGraph with optimizations for searching (e.g. storing Edge objects by their respective IDs in an array for memory-efficient storage while using Map-based storage in the mutable version). In this way, making two separate classes for two specific tasks may be quicker for the programmer as well as for the computer to deal with.

How can I reuse collections that would use the same backing iterator?

I'm fairly new to Java so my knowledge is pretty limited. I'm working on a personal project where I'm trying out some of the techniques used in Guava for creating views/transformations of collections. I made a class called View to take an inputted collection as the backing iterable, and a transformation, and then present it as a read-only iterable. (not a collection, though I don't think it makes much of a difference for this question). Here is a quick example of using it...
public class Node {
public enum Change implements Function<Node, Coordinate> {
TO_COORDINATE;
#Override public Coordinate apply(Node node) {
return new Coordinate(node);
}
}
private HashSet<Node> neighborNodes = new HashSet<Node>();
//various other members
public View<Coordinate> viewNeighborCoordinates() {
return new View<Coordinate>(neighborNodes, Change.TO_COORDINATE);
}
}
now if some method wants to use viewNeighborCoordinates() of this node, and then later some other method also wants to viewNeighborCoordinates() of this node, it seems wasteful to always be returning new objects, right? I mean any number of things should be able to share reference to a view of the same backing iterable with the same transformation, since all they're doing is reading through it. Is there an established way of managing a shared pool of objects which can be "interned" like Strings are? Is it just having to make some sort of ViewFactory that stores a running list of views in use, and everytime someone wants a view, it checks to see if it already has that view and hands it out? (is that even more efficient)?
As already stated, interning is possible (look at Interners), but most probably a bad idea.
Another possibility is lazy initialization of a field storing the View. Since I'm lazy as well, I only point you to a Lombok implementation. Be careful with DCL, if you want to try this. In case your class is immutable, you may need no synchronization at all, like e.g. String.hashCode.
A very simple possibility is eager initialization of a field. Assuming you need the view often, it's the best way.
But without knowing more, your current implementation is best. Beware the root of all evil.
Don't optimize without profiling or benchmarking (and if you benchmark, then do it right, i.e., using caliper or jmh. Home-baked benchmarking in Java just doesn't work).

Graph Theory Program

So right now i'm in a class learning graph theory. I thought it would be cool to make a program for it. To create different graphs, add and deleted nodes, edges and all the sort like that.
This semester I do not have no programming classes, so I'm trying to get ready for next semester when they start up again.
So far what I have is a Class called Graph Theory (Driver/Command-line) which of course runs the whole program.
Besides the driver class the main classes I have are:
--Graph: TYPES: Path, Cycle, Complete...
Because they all have lists of nodes and edges and add/deleted methods in common I made the TYPES, like path and cycle, inherit from graph so I didn't have to remake those million methods for each one.
In the driver class I have a list of all created graphs.
ArrayList<Graph> graphs = new ArrayList<Graph>();
My problem is when I started working on the Partite graph class it inherits from Graph like the others, but I can't access the methods.
I the driver when i create the Partite:
Partite p = new Partite(blah, blah);
graphs.add(p);
When I go through and get this graph from the list I can't access the methods from Partite.
How can I do this.
Because when you get elements from graphs they will be references of type Graph.
To access the methods from Partite you must add a cast to Partite.
Partite p = new Partite(blah, blah);
graphs.add(p);
Partite other = (Partite)graphs.get(0);
other.methodFromPartite();
Done.
Basic solution
If you rely on specific Partite methods (as opposed to Partite's versions of Graph's methods) you shouldn't really be holding it in an array of Graphs but if you must you can cast
Graph g=graphs.get(i);
Partite p=(Partite)g;
Be aware that if you get it wrong (attempt to cast something that isn't a Partite) you will get an exception. You can check in advance if the cast is acceptable by using instanceof
if (g instanceof Partite){
.....
}
A better concept
But as I say all this is usually a sign of bad program design. A better design would be to have only general graph behaviour triggered from reading this list (Partites would still be in the list, but they would behave as Graphs) and a seperate list of Partites being held as well for whatever different behaviour they need
An even better concept
If you can organise your program in such a way that you are only calling methods from Graph but Parties overrides some of them such that it behaves the way you want that is the ideal solution.
For example Graph has update and Partites` overrides update to do the extra work it needs as well. So
public class Graph {
public void update(){
doImportantWork();
}
}
public class Partite extends Graph{
#Override
public void update() {
super.update(); //so that the basic graph behavior happens
doPartiteSpecificImportantWork();
}
}
This is not always practical however.
This is probably because you're trying to modify your Partite object using a Graph reference to it. If you want to call sub class specific methods using parent class references, your design probably needs some modification (this is a code smell). To temporarily get around it for now you can case your Graph reference to a Partite reference.
((Partite)graphRef).[some method on partite]

Best pattern to update an object each iteration of an algorithm

I have an algorithm that alters the state of an object each generation, depending on some semi-random modifications made to a list. I made a simplification to be clearer, so assume I have two class:
public class Archive{
...
}
public class Operation{
...
}
In another class,Algorithm, a method iterates, make some adjustments to a List<Operation> (similar to Genetic Algorithm crossovers and mutations). This list among with other objects related are used to update an Archiveobject, making a lot of calculations and modifications to the Archive object.
In the current version of my code I have a ArchiveUpdateclass that has a internal Archive object and a method that receives ALL the objects used in the update to change the Archive. I think this way is kinda fuzzy and I can't think of another way of doing this better, can anybody help?
Have you considered making the Archive immutable and providing methods that return new Archive instances based on an existing archive? That is, something like:
public class Archive {
private final String field;
public Archive(String field) { this.field = field; }
public Archive changeField(String newField) { return new Archive(newField); }
}
If your objects are all immutable, it's much easier to reason about their state and you wouldn't need an ArchiveUpdate class. However, without more examples of exactly how these classes get used I can't suggest much else.
Its hard to grasp completely...but from what I understood you need a pattern that would allow you to be notified if a "monitored" state changed. If that is the case you should look at Observer pattern it provides a simple way of monitoring state changes.

Giving a class member a reference to another classes members

On a scale of one to ten, how bad is the following from a perspective of safe programming practices? And if you find it worse than a five, what would you do instead?
My goal below is to get the data in the List of Maps in B into A. In this case, to me, it is ok if it is either a copy of the data or a reference to the original data. I found the approach below fastest, but I have a queasy feeling about it.
public class A {
private List<Map<String, String>> _list = null;
public A(B b) {
_list = b.getList();
}
}
public class B {
private List<Map<String, String>> _list = new ArrayList<Map<String, String>>();
public List<Map<String, String>> getList() {
// Put some data in _list just for the sake of this example...
_list.add(new HashMap<String, String>());
return _list;
}
}
The underlying problem is a bit more complex:
From a security perspective, this is very, very bad.
From a performance perspective, this is very, very good.
From a testing perspective, it's good because there is nothing in the class that you can't easily reach from a test
From an encapsulation perspective, it's bad since you expose the inner state of your class.
From a coding safety perspective, it's bad because someone will eventually abuse this for some "neat" trick that will cause odd errors elsewhere and you will waste a lot of time to debug this.
From an API perspective, it can be either: It's hard to imagine an API to be more simple but at the same time, it doesn't communicate your intent and things will break badly if you ever need to change the underlying data structure.
When designing software, you need to keep all of these points in the back of your mind. With time, you will get a feeling which kinds of errors you make and how to avoid them. Computers being as dump and slow as they are, there is never a perfect solution. You can just strive to make it as good as you can make it at the when you write it.
If you want to code defensively, you should always copy any data that you get or expose. Of course, if "data" is your whole data model, then you simply can't copy everything each time you call a method.
Solutions to this deadlock:
Use immutables as often as you can. Immutables and value objects are created and never change after that. These are always safe and the performance is OK unless the creation is very expensive. Lazy creation would help here but that is usually its own can of worms. Guava offers a comprehensive set of collections which can't be changed after creation.
Don't rely too much on Collections.unmodifiable* because the backing collection can still change.
Use copy-on-write data structures. The problem above would go away if the underlying list would clone itself as soon as A or B start to change it. That would give each its own copy effectively isolation them from each other. Unfortunately, Java doesn't have support for these built in.
In this case, to me, it is ok if it is either a copy of the data or a reference to the original data.
That is the sticking point.
Passing the object instance around is the fastest, but allows the caller to change it, and also makes later changes visible (there is no snapshot).
Usually, that is not a problem, since the caller is not malicious (but you may want to protect against coding errors).
If you do not want the caller to make changes, you could wrap it into an immutable wrapper.
If you need a snapshot, you can clone the list.
Either way, this will only snapshot/protect the list itself, not its individual elements. If those are mutable, the same reasoning applies again.
I would say that you will have too choose between efficiency and encapsulation. By directly accessing a member of the class it will have its state changed. That might be unexpected and lead to nasty surprises. I would also say that it increases the coupling between the two classes.
An alternative is to let the information expert principle decide and leave the job to the class that have the information. You will have to judge if the work that was suppose to be done with class A really is the responsibility of class B.
But really, speed and clean code can be conflicting interests. Some times you just have to play dirty to get it quick enough.
All you're creating is a reference to B._list. So 10 if you wanted to copy the items.
You could iterate over all b._list items and add them to the A._list manually:
public A(B b) {
_list = new List<Map<String, String>> ();
for (Map<String,String> map : b.getList()) {
Map<String,String> newMap = new HashMap<String,String>();
while(map.keySet().iterator().hasNext()) {
String key = map.keySet().iterator().next();
newMap.put(key,map.get(key));
}
_list.add(newMap);
}

Categories

Resources