How to safely publish a mutable object? - java

I don't want to do the deep copy way.
Say, I have a field of some mutable type, a x,y,z Coordinate for example. Occasionally, I need to expose this field to some viewers. And I want it be read-only. I remember reading something like a wrapper to do these kind of stuff, but I don't remember the details.
The x,y,z Coordinate example may be too simple because x,y,z are primitive type. So getX() always return a copy.
I want a general solution even if the x,y,z fields are of yet another mutable type.
Can anybody help?
EDIT:
public class Client
{
public static final Holder holder = new Holder();
public static void main(String[] args)
{
UserWrapper user = holder.getUser();
System.out.println(user); //UserWrapper{user=User{address=Address{street='street 101'}}}
user.getAddress().setStreet("mars"); //UserWrapper{user=User{address=Address{street='mars'}}}
System.out.println(user);
}
}
public class Holder
{
private User user;
public Holder()
{
user = new User();
Address address = new Address();
address.setStreet("street 101");
user.setAddress(address);
}
public UserWrapper getUser()
{
return new UserWrapper(user);
}
}
public class User
{
private Address address;
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
}
public class UserWrapper
{
private User user;
public UserWrapper(User user)
{
this.user = user;
}
public Address getAddress()
{
return user.getAddress();
}
}
EDIT:
credit to I don't know who(he deletes the answer), I find this link he mentioned in his original post very helpful.

The traditional ways:
deep copy - prevents mutations from impacting the client who is reading
immutable objects - instead of copying for the client, you copy to update and the client gets an old pointer reference.
customer iterator - you provide your own iterator / navigation interface, which is sensitive to a "version" field embedded with the data structure. Before visiting each element, it checks that the version has not been changed since the iterator was created (java collections does this).
strong synchronization - while a reader is reading, the reader holds a lock on the data structure preventing update. Generally a bad solution, but occasionally useful (included for completeness).
lazy copy - you construct an object that mostly references the original, but is triggered (as a listener) to the original, such that when a mutation is done on the original, you copy the pre-mutated value locally.
This is like a lazy deep copy strategy.
There's others, but this should get you started.

There is no built-in mechanism in Java that will enable you to do that. Usually, if you move instances around, you'd either:
Use immutable objects
Pass on copies of the objects
Since you don't want/can't choose either of these ways, you'll need to use an alternative. There are a lot of different ways to implement this depending on your requirements and how complex is your class structure, but the general approach would be to publish an immutable wrapper instead of the original.
Here are some examples:
public class XYZ {
public int x, y, z;
}
public class XYZWrapper {
private XYZ xyz;
public XYZWrapper(XYZ xyz) {
this.xyz = xyz;
}
public int getX() { return x; }
public int getY() { return y; }
public int getZ() { return z; }
}
public class Address {
public String name;
public XYZ xyz;
}
public class AddressWrapper {
private String name; // Note that this could be public since any String is immutable
private XYZWrapper xyzWrapper;
public AddressWrapper(String name, XYZ xyz) {
this.name = name;
this.xyzWrapper = new XYZWrapper(xyz);
}
public String getName() {
return name;
}
public XYZWrapper getXYZWrapper() {
return xyzWrapper;
}
}
Now, if instead of XYZ and Address classes, you work with interfaces, you can have 2 implementations (e.g. XYZMutable & XYZImmutable) which will allow you to abstract which type of class you're returning, and also will enable you to create an instance of XYZImmutable from an instance of XYZMutable (assuming that the interface defines only & all getter methods).
One more note about this approach (especially if you do it the preferred way by using interfaces): Even if you have a complex class hierarchy, you can do this relatively effortlessly by creating a generator class that receives an interface instance, a mutable implementation instance and returns an immutable implementation instance as the return value.

Perhaps you're thinking of the "copy on write" idiom. This allows you to avoid copying unless you have to. It's use is generally not recommended because it is not thread-safe unless you use synchronization which will unnecessarily slow down single-threaded applications.
It works by keeping a reference count of its internal data; something like this untested bit of code:
public class User
{
private int addressReferenceCount;
private Address address;
public User(Address address) {
addressReferenceCount = 0;
this.address = address;
}
public Address getAddress() {
addressReferenceCount++;
return address;
}
public void setAddress(Address address)
{
if (addressReferenceCount == 0) {
this.address = address;
}
else {
this.address = new Address(address);
addressReferenceCount = 0;
}
}
}
This ensures that user code like this will get different addresses when necessary:
User u = new User(new Address("1 Acacia Avenue"));
Address oldAddress = u.getAddress();
Address stillOldAddress = u.getAddress();
u.setAddress(new Address("2 Acacia Avenue"));
Address newAddress = u.getAddress();
assert (oldAddress == stillOldAddress); // both refer to same object
assert (oldAddress != newAddress);

Related

Is there a way to efficiently audit statistics attributes of objects in Java?

Say I have a class Person, and I created 10 instances of Person, and each person has several different attributes, such as enum Gender{MALE, FEMALE}, enum Profession{CEO, POLICE, TEACHER}, etc.
And I somehow have to randomly create many persons with random attributes and use a dedicated class to audit the statistics of created persons' attributes.
So, eventually, I need to generate a list of attributes with some statistics accordingly, such as, "FEMALE: [number], POLICE: [number],...".
Currently, I'm planning to add all kinds of the persons' attributes count, as a bunch of new attributes to the audit class, such as, "femaleCount int, policeCount int, ..." then manipulate the counts based on generated persons.
But, I got 10-ish attributes for each person, so I wonder if there is a better way to do this.
Thanks for your reading.
One possible approach is below, but do not say that it's the only one neither the best.
It's only depends of the purpose and your design.Other option maybe it's to store all Persons in a data-structure List and just compute the statistic based on data at a certain time (have also update/delete here)
Version where only add is counting ...
public class Statistic
{
private static Statistic s=null;
public int countPerson;
public int countMale;
public int countFemale;
public static Statistic getInstance()
{
if(s==null)
s = new Statistic(0, 0, 0);
return s;
}
public static Statistic getInstace(int cP,int cM, int cF)
{
if(s==null)
s = new Statistic(cP, cM, cF);
return s;
}
//do whatever init wanted
private Statistic(int cP,int cM, int cF)
{
countPerson = cP;
countMale = cM;
countFemale = cF;
}
public String toString()
{
return "Total="+countPerson+", Male="+countMale+", Female=" + countFemale;
}
}
...
public class Person
{
public int id;
public String name;
public Gender g;
public Profession p;
public enum Gender{MALE, FEMALE};
public enum Profession{CEO, POLICE, TEACHER}
Person(int id,String name, Gender g, Profession p)
{
this.id = id;
this.name = name;
this.g = g;
this.p = p;
Statistic.getInstance().countPerson++;
if(g.equals(Gender.MALE))
{
Statistic.getInstance().countMale++;
}
else
{
Statistic.getInstance().countFemale++;
}
}
}
...
public class TestStat {
public static void main(String[] args)
{
//cPersons,cMale,cFemale - init
Statistic.getInstace(10, 5, 5);
System.out.println(Statistic.getInstance());
new Person(1,"Male",Person.Gender.MALE, Person.Profession.TEACHER);
System.out.println(Statistic.getInstance());
new Person(2,"Female",Person.Gender.FEMALE, Person.Profession.CEO);
System.out.println(Statistic.getInstance());
}
}
Output
//custom start from (10,5,5) based on Singleton Custom Constructor
Total=10, Male=5, Female=5
//start update counters
Total=11, Male=6, Female=5
Total=12, Male=6, Female=6
Thinking twice maybe it's better to keep a List with Persons on Singleton
and make each time a new Computation - from Singleton instead on Person.
About Delete a person which can be translated in "moving from a Company to other" and then it's not to be reflected on Statistic.
Even so, on current you could add a delete method on person which could be reflected with adjust Statistic with minus and Person-Instance with null.
Further, it's up to you to update design as wanted.

Best way to store collection of objects in Java?

I am creating a dump Java app for student information system for learning and implementing OOPS Concepts like inheritance, abstraction, polymorphism and encapsulation.
What I am doing is, I have created Faculty Class, Student Class and a College Class. Now i want to add new faculty in College. So my approach is to create a method in College class i.e. addFaculty(Faculty f) and fireFaculty(Faculty f), now i want to add Faculties in College class.
Whats the best way to do it? How do i store list of Faculty Object in College Object. Because i can add more than one faculty and more than one student in college.
Whats the best approach to solve this problem in OOPS?
Here is College.java code which i have implemented, it works fine but is this the best way i can solve it?
public class College
{
String name;
String location;
String courses[];
HashMap<String,Faculty> faculties;
int noOfFaculties = 0;
int noOfStudents = 0;
public College(String name,String location,String courses[])
{
this.name = name;
this.location = location;
this.courses = courses;
faculties = new HashMap<>();
}
public void addFaculty(Faculty faculty)
{
faculties.put(faculty.getName(),faculty);
}
public void printFaculties()
{
Set<String> set = faculties.keySet();
if(set.size()>0)
{
for(String s:set)
{
System.out.println(faculties.get(s).getName());
}
}
else
{
System.out.println("No Faculties Currently Working");
}
}
public void fireFaculty(Faculty faculty)
{
faculties.remove(faculty.getName());
}
public String getName()
{
return name;
}
public String getLocation()
{
return location;
}
public String[] getCourses()
{
return courses;
}
}
If you cannot have duplicates use HashSet<Faculty> if you dont mind use a List<Faculty>.
Example:
class College {
private List<Faculty> listFactories = new ArrayList<>(); // dupes allowed
private Set<Faculty> setFactories = new HashSet<>(); // no dupes allowed
}
Check collections API.
There's a ton of ways you can do it. Probably the easiest way to handle storing a collection of objects is by using one of the Collections provided by Java. For beginners, probably the easiest one to understand is an ArrayList, which is basically an array that grows in size dynamically depending on the amount of objects in the collection.
So, as an axample, your code might be something like this:
public class College
{
private ArrayList<Faculty> faculty;
public College()
{
faculty = new ArrayList<Faculty>();
}
public void addFaculty(Faculty f)
{
faculty.add(f);
}
public void fireFaculty(Faculty f)
{
faculty.remove(f);
}
}
imho It depends what kind of services College college offers. If I were coding, I would start with:-
List<Faculy> faculties = new ArrayList<>();
....
public void addFaculty(Faculty f) {
faculties.add(f);
}
//... etc
And change to an altearnative later if needed.

List of enum vs. class of booleans

For now, I have a class with fields.
#Entity
public class Fuel {
#Id #GeneratedValue
private Long id;
private boolean diesel;
private boolean gasoline;
private boolean etanhol;
private boolean cng;
private boolean electric;
public Fuel() {
// this form used by Hibernate
}
public List<String> getDeclaredFields() {
List<String> fieldList = new ArrayList<String>();
for(Field field : Fuel.class.getDeclaredFields()){
if(!field.getName().contains("_") && !field.getName().equals("id") && !field.getName().equals("serialVersionUID") ) {
fieldList.add(field.getName());
}
Collections.sort(fieldList);
}
return fieldList;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isDiesel() {
return diesel;
}
public void setDiesel(boolean diesel) {
this.diesel = diesel;
}
public boolean isGasoline() {
return gasoline;
}
public void setGasoline(boolean gasoline) {
this.gasoline = gasoline;
}
public boolean isEtanhol() {
return etanhol;
}
public void setEtanhol(boolean etanhol) {
this.etanhol = etanhol;
}
public boolean isCng() {
return cng;
}
public void setCng(boolean cng) {
this.cng = cng;
}
public boolean isElectric() {
return electric;
}
public void setElectric(boolean electric) {
this.electric = electric;
}
}
I think it makes sense, but when I asked another question (maybe a stupid example since there can only be either automatic or manual gearbox) https://stackoverflow.com/questions/11747644/selectonemenu-from-declared-fields-list-in-pojo , a user recommend me to use enums instead. Like this way:
public enum Fuel {
DIESEL("diesel"),
GASOLINE("gasoline"),
ETANHOL("etanhol"),
CNG("cng"),
ELECTRIC("electric");
private String label;
private Fuel(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
}
However, since there exists hybrids on the market (like Toyota Prius) the parent class would implement the boolean class at this way:
private Fuel fuel = new Fuel();
and if using enumerated list at this way:
private List<Fuel> fuelList = new ArrayList<Fuel>();
What is the best practice? Keep in mind that I might have 100 different fuels (just for example =). Do not forget that it is an entity and hence persisted in a database.
Thanks in advance =)
It sounds to me like you want an EnumSet, yes, definitely over a bunch of bool's.
This reminds me a lot of the design patterns for flags and I recently posted an SO question on exactly that: Proper design pattern for passing flags to an object
This supports having 100 different fuel types easily. However it doesn't support a car using 100 different fuel types simultaneously easily. But that to me sounds perfectly fine - it would be very hard to build such a car and this is perfectly reflected in the programmatic complexity of coding this :) (Unless of course it really was just supporting all corn-based fuels - in which you might prefer a polymorphic pattern.)
You should definetly use enums.
Image you want to get the fuel-type of an object.
If you would use bools you would end up with something like this:
if (myClass.IsGasoline())
else if (myClass.IsOtherFuel())
else if
...
If you use enums you can simply do something like:
Fuel fuel = myClass.GetFuelType()
(This is just pseudo-code ;))
If the number of hybrids is low, and I guess it will be better to use Enums, and include hybrids as a different case.
Otherwise you will have to manage the logic in a way that can be cumbersome, as when you set a certain Fuel to true you, most likely, will have also to set to false the current one set to true. I am saying this as you have setters for your fuel categories and you don't only define at construction.
EDIT: the way on how to ask for the type of fuel you are using would also be an argument in favor of enums.

Any nice way to make two immutable objects refer to eachother?

Take these two Java classes:
class User {
final Inventory inventory;
User (Inventory inv) {
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
Is there any way without using reflection* to pull this off? I don't actually expect it is, but it can't hurt to ask.
Update: Since in bytecode construction has two steps (1. allocate object, 2. call constructor**) could this be (ab)used to do this, with handwritten bytecode or a custom compiler? I'm talking about performing step 1 for both objects first, then step 2 for both, using references from step 1. Of course something like that would be rather cumbersome, and this part of the question is academic.
(* Because reflection may give trouble with a security manager)
(** Says my limited knowledge)
This can only work cleanly if one of the objects is created by the other. For example you can change your User class to something like this (while keeping the Inventory class unchanged):
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
You need to be careful about accessing the User object in the Inventory constructor, however: it's not fully initialized yet. For example, its inventory field will still be null!
Ad Update: I've now verified that the bytecode-manipulation approach does not work. I've tried it using Jasmin and it always failed to load with a VerifyError.
Delving deeper into the issue, I foundĀ§ 4.10.2.4 Instance Initialization Methods and Newly Created Objects. This section explains how the JVM ensures that only initialized object instances get passed around.
You can do it if you don't need to inject one of the objects.
class User {
private final Inventory inventory;
User () {
inventory = new Inventory(this);
}
}
class User {
private final Inventory inventory;
User (/*whatever additional args are needed to construct the inventory*/) {
//populate user fields
inventory = new Inventory(this);
}
}
class Inventory {
private final User owner;
Inventory (User own) {
owner = own;
}
}
That's the best I can think of. Maybe there's a better pattern.
Slightly pedantic, but it's not strictly speaking necessary to create one inside the other, if you don't mind a little indirection. They could both be inner classes.
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User() {
... has access to BadlyNamedClass.this.inventory;
};
this.inventory = new Inventory() {
... has access to BadlyNamedClass.this.owner;
};
}
...
}
Or even:
public class BadlyNamedClass {
private final User owner;
private final Inventory inventory;
public BadlyNamedClass() {
this.owner = new User(this);
this.inventory = new Inventory(this);
}
public User getOwner() { return owner; }
public Inventory getInventory() { return inventory; }
...
}
This is one "solution", though the loss of one final is inconvenient.
class User {
Inventory inventory;
User () { }
// make sure this setter is only callable from where it should be,
// and is called only once at construction time
setInventory(inv) {
if (inventory != null) throw new IllegalStateException();
inventory = inv;
}
}
class Inventory {
final User owner;
Inventory (User own) {
owner = own;
}
}
If you are only interested in JVM bytecode and don't care about coding in Java specifically, perhaps using Scala or Clojure could help. You'll need some kind of letrec machinery.
B: "Inventory created by the User is our last hope".
Y: "No, there is another."
If you abstract the references to a third party, you can control the relationship therein.
For example.
public class User
{
private final String identifier; // uniquely identifies this User instance.
public User(final String myIdentifier)
{
identifier = myIdentifier;
InventoryReferencer.registerBlammoUser(identifier); // Register the user with the Inventory referencer.
}
public Inventory getInventory()
{
return InventoryReferencer.getInventoryForUser(identifier);
}
}
public interface Inventory // Bam!
{
... nothing special.
}
// Assuming that the Inventory only makes sence in the context of a User (i.e. User must own Inventory).
public class InventoryReferencer
{
private static final Map<String, Inventory> referenceMap = new HashMap<String, Inventory>();
private InventoryReferencer()
{
throw ... some exception - helps limit instantiation.
}
public static void registerBlammoUser(final String identifier)
{
InventoryBlammo blammo = new InventoryBlammo();
referenceMap.add(indentifier, blammo);
}
public static void registerKapowUser(final String identifier)
{
InventoryBlammo kapow = new InventoryKapow();
referenceMap.add(indentifier, kapow);
}
public static Inentory getInfentoryForUser(final String identifier)
{
return referenceMap.get(identifier);
}
}
// Maybe package access constructors.
public class InventoryBlammo implements Inventory
{
// a Blammo style inventory.
}
public class InventoryKapow implements Inventory
{
// a Kapow style inventory.
}

Implementation question regarding base classes and derived classes

I have a question regarding the best way to implement this. I'm going to describe my current implementation and how I seem to have painted myself into a corner:
I have an abstract class called Package:
public abstract class Package {
protected String description;
protected String packagingCode;
protected Dimension dimensions;
protected Weight weight;
protected Package() {
this.description = null;
this.packagingCode = null;
this.dimensions = null;
this.weight = null;
}
protected Package(String description, String packagingCode, Dimension dimensions, Weight weight) throws ShippingException {
this.description = description;
this.packagingCode = packagingCode;
this.dimensions = dimensions;
this.weight = weight;
String exceptionMessage = "";
if(!meetsWeightRequirements()) {
exceptionMessage = "This package's weight exceeds limits. ";
}
if(!meetsDimensionalRequirements()) {
exceptionMessage += "This package's dimensions exceed limits.";
}
if(!StringUtils.isEmpty(exceptionMessage)) {
throw new ShippingException(exceptionMessage);
}
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPackagingCode() {
return packagingCode;
}
public void setPackagingCode(String packagingCode) {
this.packagingCode = packagingCode;
}
public Dimension getPackageDimensions() {
return dimensions;
}
public void setPackageDimensions(Dimension dimensions) throws ShippingException {
this.dimensions = dimensions;
if(!meetsDimensionalRequirements()) {
this.dimensions = null;
throw new ShippingException("This package's dimensions exceed limits.");
}
}
public Weight getPackageWeight() {
return weight;
}
public void setPackageWeight(Weight weight) throws ShippingException {
this.weight = weight;
if(!meetsWeightRequirements()) {
this.weight = null;
throw new ShippingException("This package's weight exceeds limits.");
}
}
public abstract boolean meetsWeightRequirements();
public abstract boolean meetsDimensionalRequirements();
}
Then I have classes that extend this abstract class like so:
public class WeightBasedPackage extends Package {
public boolean meetsWeightRequirements() {
Weight weight = this.getPackageWeight();
boolean meetsRequirements = false;
if(weight != null) {
meetsRequirements = (weight.getWeight() > 0);
}
return meetsRequirements;
}
public boolean meetsDimensionalRequirements() {
return true;
}
}
I have another object (ShipRequest) that maintains a List of Packages (List<Package>). I also have a services (eg WeightBasedPackageShipService) that uses this object and can access this list of packages. This implementation has worked fine because the services don't really care what type of package it is. The only difference between the packages is the way they implement the abstract methods.
Now here is where the problem comes in. I created a new class:
public class OrderQuantityPackage extends Package {
int quantity;
public OrderQuantityPackage() {
super();
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getQuantity() {
return this.quantity;
}
public boolean meetsWeightRequirements() {
return true;
}
public boolean meetsDimensionalRequirements() {
return true;
}
}
Which has a quantity field. I need to access this field in the service (OrderQuantityPackageShipService). However, since it is of type Package I have to cast it (it seems kinda kludgey).
My question is, how do I implement this in a better fashion (so I don't have to cast) and also ensure type-safety (So that if you are using OrderQuantityPackageShipService, the package must be of type OrderQuantityPackage). I thought about using Generics, but it seems a little to kludgey for what I am trying to do (ShipRequest has a bunch of other attributes and it seemed strange to genericize it based on the type of package).
Thanks.
public abstract class Package {
protected String description; // These shouldn't be private fields instead of protected?
protected String packagingCode; // Nah, I don't think so, otherwise how could I store a value into the Quantity field? =P
protected Dimension dimensions;
protected Weight weight;
protected int quantity;
// Constructors, getters and setters...
public virtual int getQuantity {
throw new NotImplementedException();
}
public virtual int setQuantity(int quantity) {
throw new NotImplementedException();
}
}
public final class OrderQuantityPackage extends Package {
public override int getQuantity {
return super.quantity;
}
public override void setQuantity(int quantity) {
super.quantity = quantity;
}
}
I'm not completely sure about the syntax though, and neither about the NotImplementedException, but I hope you get the idea. So, any Package derived class that needs or require a quantity may do so by overriding the getter and setter of the Quantity property.
No exception should be thrown as of where the Quantity won't be required, it shouldn't get called, so no exception shall be thrown. Furthermore, it testifies that your model only does what it is required when times come.
In addition to it, OrderQuantityShipService shouldn't require a Weight property within the OrderQuantityPackage, and as written by Vivin, one could access the weight anyway.
Otherwise, a simple cast within your service should do it. It is no dirty way to go to use casting. For instance, one must cast the sender object within an event handler to the proper control type he wishes to check for name, state or other property values! The most general class is then passed on to the event, and one must cast... And this, that is not me who said to opt this way, these are software engineers!...
EDIT Vivin, how do one cast from a data type to another in JAVA, is it as in C/C++/C# ?
CastedType variable = (CastedType)TypeCast;
Short Answer: Dependency Inversion
You have a OrderQuantityPackageShipService class that requires certain features from the objects that it processes. So OrderQuantityPackageShipService should be the one specifying those requirements. Typically this is done with an interface. If it is very specific to the service, create the interface nested. ie:
class OrderQuantityPackageShipService {
//...
interface QuantityPackage {
int getQuantity();
// ...
}
}
if it can be used in a consistent manner by other services, define it outside of the OrderQuantityPackageShipService class.
Then have certain packages implement that interface...
Maybe you should create an abstract service and extend it for the different kinds of packages to handle. You could have the handling method be abstract and have each kind of service know what to do with the corresponding package. If you're not to mix types of packages then this might work.
One thing I can think of is why would you need to access the quantity attribute in the class OrderQuantityPackageShipService ? As I look at it you have a getter and setter for each attribute of the class Package. Are these getters and setters really needed ? Having getters/setters for all those attributes doesn't go well with encapsulation.
Can you think of providing public methods in Package class that operate at a higher level and don't expose the internal attributes ? Wouldn't that help ?

Categories