Win a copy of React Cookbook: Recipes for Mastering the React Framework this week in the HTML Pages with CSS and JavaScript forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

create a 'singlton' patter for each unique hashcode of class

 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I want to have something similar to a singlton concept, but I don't want the class to be unique. I can have multuple instances, but any time a user tries to create a new instance which would be evaluate as Equal (in Object.equals() sense) to an existing instance I want to return the existing instance rather then generating a new object. So I'm doing a variant of a lazy sington pattern, where each unique hash results in a new unique instance. Further, I want to have this 'singlton-like' patter built into an abstract class that multuple classes will inherrit.

I could almost do this. I know I could use a factory pattern backed by a WeakHashMap to decide rather the object is unique (weak so that if I'm done with the object it's cleared out of memory). My problem is the abstract method. I can create a single protected constructor and provide a protected static factory method which I *want* everyone generating myObject to call when they want to generate the object. The problem is that I have no way of enforcing this constraint on anyone inherriting my class; how do I make them call my abstract class's factory method?

The reason I want this is that i"m trying to create a model with a number of closely interconnected objects. These objects have some fields which uniquly define what node/edge/whatever they are, and other private fields maintained by the model objects to maintain state. I want anyone trying to create a new node/edge/path/etc to end up with the already existing node/edge/path/etc which includes all the interconnected state information.
 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

drew sollenberger wrote:I want to have something similar to a singlton concept, but I don't want the class to be unique. I can have multuple instances, but any time a user tries to create a new instance which would be evaluate as Equal (in Object.equals() sense) to an existing instance I want to return the existing instance rather then generating a new object. So I'm doing a variant of a lazy sington pattern, where each unique hash results in a new unique instance.



Note that two unequal objects can have equal hashCodes. So by the first part of what you said--"if the objects are equal, return the existing one"--you could also have a new instance created on a non-unique hash.

So you need to clarify whether it's hashCode or equality that you'll use to determine whether to use an existing instance.

My problem is the abstract method. I can create a single protected constructor and provide a protected static factory method which I *want* everyone generating myObject to call when they want to generate the object. The problem is that I have no way of enforcing this constraint on anyone inherriting my class; how do I make them call my abstract class's factory method?



You're saying you want subclasses to call this method as part of their own construction process? Then just call it in your protected constructor. Or set a flag that only gets flipped when they call that method, and then check that flag's value.

If you're not able to do that, then you'll just have to document the requirement and accept the fact that anyone who violates the documented correct usage of your class will have nobody to blame but themselves when their code doesn't work.
 
drew sollenberger
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Note that two unequal objects can have equal hashCodes.



Technically yes, but if so your breaking part of the presumed contract for these two methods and many Collections start to do bizzare and mesed up behavior. I said haschode in my description only because it was a little easier to explain what I was thinking in a concise title that way; and I assume that I'm going to implement my hashcode and equals methods correctly so that the two are equvilant. Technically I would decide rather I wanted a new instance by seeing if any of the fields I consider to uniquly define each object are different, but I'll also be writing my equals, and hashCode, methods to only use those fields as well; and I'm fine with assuming all of that because that's just staying true to the intent of equals and hashCode.

Then just call it in your protected constructor. Or set a flag that only gets flipped when they call that method, and then check that flag's value.



I don't think I can do this in the constructor. My goal is to return an existing, already instantiated, object if one already exists for a specific node/edge (or whatever the class is). I can't do that within a constructor call, since by the time I've reached the constructor a new object has already been instantiated and it's too late to say "no wait I changed my mind, use this object instead!". I'm relatively confident that I need some sort of static factory method somewhere.

If you're not able to do that, then you'll just have to document the requirement and accept the fact that anyone who violates the documented correct usage of your class will have nobody to blame but themselves when their code doesn't work.



I very well could do that, and may do so. I suppose I"m just asking rather this seems something reasonable to place as an expecation or too prone to confusing someone. Also, if anyone can think of a better approch which wouldn't require my making assumptions about how others utilize my code?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

drew sollenberger wrote:

Note that two unequal objects can have equal hashCodes.



Technically yes, but if so your breaking part of the presumed contract for these two methods and many Collections start to do bizzare and mesed up behavior.



Not at all.

SImple counterexample: There are 2^64 values for Long. There are 2^31 values for hashCode(). Therefore, there must be a lot of overlap among Longs' hashCodes.

HashCode is not meant to be unique, and hash based collections don't assume it is or rely on it being unique. All they care about is 1) that equals objects have equal hashCodes, for correct operaiton, and 2) that hashcodes be well distributed, for performance.


I assume that I'm going to implement my hashcode and equals methods correctly so that the two are equvilant.



That works if you have sufficient control over the states of your objects. For example, if every one simply has an int field, that int can be your hashCode and the sole determinant of equality. However, if your object can have a String field of more than a few characters--or in any way has more than 4 bytes of state--you're going to have a bugger of a time trying to make hashCode() and equals() equivalent--that is, making hashCode() unique for all the possible states of your objects.

But there's no good reason to do that anyway.
 
drew sollenberger
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are correct, I forgot about the pigeonhole theorm and all of that. All that is required is that two objects that are equal have the same hash, there is nothing preventing two non-equal objects from also having the same hash. I did speak incorrectly in the title, but in my defense I had only been trying to condense the idea to a catchy title and hadn't given the implication as much thought. What I want to do though, is still the same. I offically want one object for every instance that is not Equal to any existing one.

Any thoughts on that problem? it sounds as if your view is that I should jsut do it and notate it and it won't be too confusing? ther is no pattern to better encapsulate any of this?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

drew sollenberger wrote:
Any thoughts on that problem? it sounds as if your view is that I should jsut do it and notate it and it won't be too confusing? ther is no pattern to better encapsulate any of this?



I think I suggested a couple of possible approaches. I don't know enough about what you're trying to accomplish, your requirements, constraints, and use cases to positively recommend one concrete approach.

"Document it and let it be the user's problem" was suggested as a fallback in case the other suggestions don't fit your situation. (Although, in the end, that's part of every class.)
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It's certainly easy enough to create a factory where the user says getMeAFoo(characteristic_1, ..., characteristic_N) and then the factory fetches it from a map, creating it first if there's not already one present with those characteristics.

I'm not sure what you're trying to accomplish with the abstract base class and user-implemented subclasses though. How to do you envision it being used? getMeAFoo(ConcreteFooSubclass.class, characteristic_1, ..., characteristic_N)? If the user is defining his own subclasses, you could do something like that, and require that the subclass have a constructor that takes the args specified by the characteristics, and then use reflection to instantiate it. It will be enforced by the JVM, which is stronger than enforcing by documentation but weaker than enforcing at compile time.

 
drew sollenberger
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a model with many different things stored in it to fully represent my state. it has 'nodes' and 'edges' but there are other objects with a high interconnectivity to them. In truth the objects have too much complicated interconnectivity; I think that these objects could haev been defined differently to simplfy what they conceptually represent and remove some of the complexity in maintaining state across them; however,i'm refactoring legacy code and it's probably too late to make changes to the raw objects themselves (and I know I would never win the fight if I said I wanted to completely redefine these objects). To avoid mistakes happening I've extended the existing objects so they can store more state logic internally (rather then re-calculating all of it every time), so now edges are aware of all paths relaying on them, nodes are aware of all paths on them etc etc. My model is maintaining all this state so that a user can make a simple call to get all the state that they use to calculate on the fly each time (plus the model makes it easier to get state about things that weren't done before because of how much of a pain it was to calculate). This also allows me to ensure some consistency and error checking that was needed.

If I had my way ideally each object would be built via some sort of factory pattern from the model. However, the code is already in the field with plugins built on the *old* way of constructing objects; the old way using a Builder pattern to build things. The builders were all very basic allowing creating objects with inconsistent/impossible internal state. I'm afraid to remove this Builder approch, even if the main motivation for using it is now OBE, because of the use of the Builders in the plugins. Techinically I have access to the code for all existing plugins; but they are large and complex and, without knowing the underlying interfaces they use, I would prefer not to do much refatoring on them and risk breaking them. I would definatly add some static factory methods to wrap the builder and give something closer to a stander simply constructor though!

The reason I want to modify the existing method is that I'm worried about the manner my model receives objects and state from the plugins. First, if objects from the plugins are malformd right now it's very unclear what I should do (the plugins are suppose to represent the 'real' state). I'm also worried that child objects which contain further child objects etc etc and all of these objects are may be equvilant (Equal) to my in-model objects, but are differnt objects. I'm concerned about aliasing issues causing trouble later. I don't want to change an object passed by a plugin and wonder why it didn't change my model's state because I didn't know I was touching an alias. One option is to have ways of convernting any object from a plugin into the equivlant object in my model; but it looks potentially ugly AND either slow (if I cycle through every single object to see fi any are Equal) or brittal (if I make assumption about objects to allow faster lookups). I'm also worried that if I ever forget, somewhere, to convert an object passed to the model (or any of it's children or childrens-children's objects) to it's in-model equvlant I could break my state because changes I made to the object passed in won't be reflected in my model.

I had thought I could clean all of this up if I could write the code in such a way that a factory pattern, of some sort, was used to create these objects. Since all the objects use a Builder anyways, I can conver thte 'build' method to work as my factory. If a user tries to 'build' an object already in my state the builder just returns the existing object rather then constructing something new; if the object doesn't exist the builder constructs the object and stores it in a list of already-constructed objects. This way users always have objects which fully represent my model state, rather or not the care about the rest of that state at the moment it's available to them, and I don't have to worry about constantly converting objects passed in to their model-equvlant object before I do any work on them. Since anyone that isn't my model won't be able to change any state of these objects, instead using them as immutable objects, they could happily use these objects without any thought to the model-state information if they want. So this shouldn't break the plugins because they are unaware of the new state information I've added to these objects since the plugins were written and thus will completely ignore it.

As a side note, when I make this change I would also be ensuring that the private constructor does basic checking on consistency of objects to avoid creating an object that is cannot exist; throwing exceptions if an object with impossible state are requested. Error checking risks breaking the old plugins, if we throw an exception somewhere where the plugins are doing something wrong. We already discussed this and decided we wanted that, to find out if the plugins are doing something conceptually bad that should be fixed; were still doing agile development and it's fiesable there are flaws that haven't yet been detected in plugins.

I think I could do this and it would all work well, *for me*. My concern is that the approch may not be intuitive for others, or risk others not 'abiding' by restrictions of my abstract class. I want to palce a restriction that that any object that extens MyObject must have only a single private constructor which takes a class extending MyBuilder. Each object defines it's own private Builder which extends myBuilder, so each builder can be tailored to the fields that must be set for the appropriate child class. The Build method of the builder will be final, and before it builds anything it will check if an instance such as the one described by the builder already exists (say, by having a weakHashMap which maps Builder objects to instances that have been constructed? not commited to that approch). If an instance exists the Build returns it. If an instance doesn't exist the Builder calls the objects constructor, passing in the builder, and returns the results; after adding it to the list of instances in the hashMap.

There is some room to either use really 'strict' final methods with reflection used to make things work out in the sub-classes, or use abstract methods that define how to do some of these steps and remove reflection to speed up construction.

Anyways, this is how I sort of view doing things, but I'm not certain if it is right. I think it would work great for me, but I'm afraid it may be too complecated for others touching my code in the future. There is the concern that this all works only if the user sticks to the Builder pattern and never tries to write a public constructor. In addition I guess I'm also wondering if this is an example of me over thinking/complicating design?

 
I miss the old days when I would think up a sinister scheme for world domination and you would show a little emotional support. So just look at this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic