Entity objects getters and setters for data properties - entity

I recently started working in Java and was introduced to the wild and crazy world of getters and setters for everything. I hated it at first, but quickly got used to it. Too used to it.
I have been spending a lot of time lately thinking more about class design. One of the things I am trying to do is avoid the trap of doing getters and setters for everything. However, much of the work I do is with entities that are mainly data containers and I am not certain that getters and setters are actually inappropriate in these cases.
Here is a simple example using public properties.
class Space {
public String name;
public String description;
Space(final String name, final String description) {
this.name = name;
this.description = description;
}
}
Here is a simple example using private properties and using getters and setters.
class Space {
private String name;
private String description;
Space(final String name, final String description) {
this.name = name;
this.description = description;
}
public String getName() {
return this.name;
}
public void setName(final String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
}
In these examples, both the name and the description fields should be able to be changed.
I feel like the getter/setter example is more clear and hides the implementation details of what name and description are. It would also allow for validation on set later if needed.
I have read several discussions about getters and setters being evil and/or an anti-pattern, but it really feels like those might not apply to this situation.
Maybe there are some options I have not yet considered. I'm open for suggestions!

The first version (public properties) is not a good idea. The second is better. As Josh Bloch would say, "favor immutability":
public class Space {
private final String name;
private final String description;
public Space(final String name, final String description) {
this.name = name;
this.description = description;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
}
That being said, getters and setters tend to be overused.

You have heard the often oversimplified "get/setters are evil". Nobody (I hope) really means that there's anything wrong with it for data objects. I think the real idea is:
"Getters/Setters are evil, except for plain data storage objects" which itself is just an evangelism of "tell don't ask".
Ideally if a class has getters and setters, that's all it should have.
That's the argument anyway. I'm not sure I agree with it.

To put it simple:
You need getters for all fields that must be read from the outside.
You need setters for all fields that must be written from the outside.
This can be 100%, but most of the time it is less.

While the accessor pattern helps hide the implementation details of a class (e.g. using a hashtable to store attributes to save memory on sparsely used classes), it can be very verbose to implement (your example has 12 lines more with accessors). That's why C# has a special property syntax, which allows to concisely specify default accessors:
class Space {
public String Name { get; set; }
public String Description { get; set; }
Space(final String name, final String description) {
this.Name = name;
this.Description = description;
}
}
Alternative forms may add access specifiers and/or code:
private String _name;
public String Name {
get { if (_name == null) FetchName(); return _name; }
private set { _name = value; }
}

Related

How does the dot notation changes the internal representation for an object?

I am new to Object Oriented Programming. I have come across the concepts of Getters and Setters as well as Dot notation to manipulate the value of an object. It is suggested to use more of Getters and Setters methods instead of Dot notation method.
I tried to understand the reason behind this and found out that using the dot notation might change the internal representation of the object. But, the resource I referred did not tell how exactly this change happens.
Can someone please tell how this change actually looks like?
Thanks in advance!
Using getters and setters (or properties in some languages) is common practice because they promote encapsulation, one of the four principles of object oriented programming. The idea is that an object should have control over its own properties or members, and that outside classes should not be able to directly manipulate its properties or members.
You asked specifically about the internal representation of an object. Java, for instance, passes its members by value when you call a get function, but you are accessing the member directly with dot notation. For example take the following class:
public class Person {
public String name = "John";
public String getName() {
return name;
}
}
In this circumstance you could access the name member of the Person class through the getName() method, or you could access it through dot notation. If you use the getName() method then you can't inadvertently change the value of the name member. For example:
public static void main(String[] args) {
Person person = new Person();
String name = person.getName();
name = "Gary";
Sysetm.out.println(person.getName());
}
Will produce the output John, whereas the following:
public static void main(String[] args) {
Person person = new Person();
person.name = "Gary";
Sysetm.out.println(person.getName());
}
Will produce the output Gary.
The accepted practice for handling this person class is to use encapsulation, and set a private access modifier for its member, like so:
public class Person {
private String name = "John";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now you can explicitly set the name member to whatever you would like using the setName method, but you will never be able to inadvertently change the name member by using dot notation.
Furthermore, there will often be times when you will want to do something with the member before it is returned or before it is set. A simple example would be the following:
public class Person {
private String name = "John";
public String getName() {
return name;
}
public void setName(String name) {
// null values are not allowed, and a name must be at least two characters long
if (name == null || name.length() < 2) {
return;
}
// name must be capitalzed
name = name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
this.name = name;
}
}
In summation, we do it this way because encapsulation makes code cleaner, more predictable, and more maintainable. I hope this helps!

Can I refer to properties directly in entity constructor with EclipseLink?

EclipseLink version is 2.5.1
We've moved from GlassFish web-server to TomCat. This made us switch to static weaving because with TomCat dynamic weaving doesn't really work that easy.
Now that static weaving works, it seems to work quite a bit differently.
If I have an entity which sets some property directly in the constructor:
class Entity {
#Column
private String name;
public Entity() {
name = "something";
}
public String getName() {
return name;
}
}
Long story short this test will fail:
Entity e = new Entity();
assertEquals("something", e.getName()); // e.getName() returns null
This happens because getName(), after weaving, is not returning this.name anymore. Instead it calls a routing for initialization (if it's needed) and (I guess) gets the value of the property from some underlying HashMap.
But constructor is not being weaved, I even have looked into the sources of weaver and seems to be explicitly opting out of this:
/**
* Construct a MethodWeaver and allow it to process the method.
*/
#Override
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, methodName, desc, signature, exceptions);
if (!alreadyWeaved) {
// skip constructors, they will not changed
if (!"<init>".equals(methodName) && !"<cinit>".equals(methodName)) {
// remaining modifications to the 'body' of the class are
// delegated to MethodWeaver
mv = new MethodWeaver(this, methodName, desc, mv);
}
}
return mv;
}
The question is, maybe I miss something here? Is it the actual reality with EclipseLink 2.5.1 that you can't use properties directly in entity's own ctor? (and it's not even mentioned anywhere, not googlable at least)
It turns out yes, we can.
But there was a problem that led us to the property being not visible to the getter.
We actually have MappedSuperclass inheritance here and we were shadowing this field in the child class. Essentially this:
class A {
#Column()
protected String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class B extends A {
#Column()
protected String name;
// no #Override here
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
So we were just shadowing the property.

How to provide hints to IntelliJ to exclude properties when using generate

With IntelliJ 2016.2 is there a way to mark a property/method that should not be included when generation of code is done?
For example this class
public class Person {
private String firstName;
private String lastName;
public void setFirstName(String firstName){ ... }
public String getFirstName() { ... };
public void setLastName(String firstName){ ... }
public String getLastName() { ... };
public String getFullName() { // returns first + last };
}
I would like to mark getFullName so it is not used when generating things like equals or toString since it is merely a connivence function.
This isn't a full answer, but when you generate equals/hashcode, the first screen has an option to select a template. Choose "..." and you can create your own new template for creating equals and hashcode. You might therefore be able to code something, eg reading an annotation on a field, that would allow you to exclude it from the generation.
These look suspiciously like Velocity macros to me but my understanding of them isn't good enough to take the solution any further.

Am I breaking the "Law of Demeter"?

I just recently became aware of the Law of Demeter.
Like a lot of things, I realized that it was something that I was already doing but did not have a name for. There are a few places though that I seem to violate it.
For example...
I might have an Address object:
public class Address : IAddress
{
public string StreetAddress { get; set; }
public string City { get; set; }
public int Zip { get; set; }
}
and a Customer object:
public class Customer : ICustomer
{
private IAddress address;
Customer()
{
Address = null;
}
public string Name { get; set; }
public IAddress
{
get
{
if (address == null)
{
address = new Address();
}
return address;
}
set
{
address = value;
}
}
}
Ok, this is fake code so you probably do not have to jump on me to use IoC to eliminate the new Address() or anything but it is pretty much an example of what I am doing. I did not include the interfaces as I am hoping they are obvious.
I would then use it in my code for stuff like int zip = customer.Address.Zip; and customer.Address.City = "Vancouver";
As I understand it, I am violating the Law of Demeter by manipulating details of Address from Customer.
Then again, it seems like the framework does as well. After all, wouldn't address.City.Length be a violation? Should I be adding methods to Address to handle accessing string properties? Probably not. So, why clutter up Address?
I cannot really just add methods to Address that relate only to customer. I have Member, Employee, Dependent, Vendor, Employer, etc. objects that all have addresses too.
Is there a better way to handle this? What kinds of problems am I risking if I use Address the way I am now?
For the Java folks, the Address class might look something more like the following if it helps:
public class Address extends AddressInterface
{
private String m_city;
public String getCity() { return m_city; }
public void setCity(String city) { m_city = city; }
}
I must admit that customer.getAddress().setCity("Vancouver"); rings more alarms than customer.Address.City = "Vancouver"; did for me. Maybe I should switch to Java for a while.
This article: http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx has a great explanation of the issues you are discussing.
As he notes it's not a dot counting exercise, it's a coupling issue. Currently your Customer and Address classes are too tightly coupled. For starters, Customer shouldn't be making new addresses, perhaps pass an Address in using a constructor. As to whether you should be using multiple dots to access parts of the address, read the article ...
Martin Fowler: "I'd prefer it to be called the Occasionally Useful Suggestion of Demeter."
Violations of the Law of Demeter are instances of a code smell named Inappropriate Intimacy. To remove this smell, you can refactor your code by hiding the internals of address and implementing methods in Customer that delegate to address. This way, you respect the encapsulation on the address inside the Customer.
Example:
public class Customer extends ICustomer{
private Address address;
....
public void setCity(String city){
address.setCity(city);
}
public String getCity(){
return address.getCity();
}
}
Hope this helps.
The problem here is that Address is a ValueObject. You would never change the city without changing the zip.
public class Customer extends ICustomer{
private Address address;
....
public void setAddress(String street, String city, int zip){
address = Address.new(street, city, zip);
}
// or even better but i'm not sure if it's valid C#
public void setAddress(int zip){
address = Address.lookup(zip);
}
}

How to persist an enum using NHibernate

Is there a way to persist an enum to the DB using NHibernate? That is have a table of both the code and the name of each value in the enum.
I want to keep the enum without an entity, but still have a foreign key (the int representation of the enum) from all other referencing entities to the enum's table.
Why are you guys over complicating this? It is really simple.
The mapping looks like this:
<property name="OrganizationType"></property>
The model property looks like this:
public virtual OrganizationTypes OrganizationType { get; set; }
The Enum looks like this:
public enum OrganizationTypes
{
NonProfit = 1,
ForProfit = 2
}
NHibernate will automatically figure it all out. Why type more than you need????
You can use the enum type directly: http://web.archive.org/web/20100225131716/http://graysmatter.codivation.com/post/Justice-Grays-NHibernate-War-Stories-Dont-Use-Int-If-You-Mean-Enum.aspx. If your underlying type is a string, it should use the string representation, if it is numeric, it will just use the numeric representation.
But your question wording sounds like you're looking for something different, not quite an enum. It seems that you want a lookup table without creating a separate entity class. I don't think this can be done without creating a separate entity class though.
An easy but not so beautiful solution:
Create an integer field with and set the mapping in the mapping file to the field.
Create a public property that uses the integer field.
private int myField;
public virtual MyEnum MyProperty
{
get { return (MyEnum)myField; }
set { myField = value; }
}
I am using NHibernate 3.2, and this works great:
type="NHibernate.Type.EnumStringType`1[[enum_full_type_name, enum_assembly]], NHibernate"
Not sure when the generic EnumStringType got added, though.
Try using a stategy pattern. Uou can then put logic into your inner classes. I use this quite alot espically when there is logic that should be contained in the "enum". For example the code below has the abstract IsReadyForSubmission() which is then implemented in each of the nested subclasses (only one shown). HTH
[Serializable]
public abstract partial class TimesheetStatus : IHasIdentity<int>
{
public static readonly TimesheetStatus NotEntered = new NotEnteredTimesheetStatus();
public static readonly TimesheetStatus Draft = new DraftTimesheetStatus();
public static readonly TimesheetStatus Submitted = new SubmittedTimesheetStatus();
//etc
public abstract int Id { get; protected set; }
public abstract string Description { get; protected set; }
public abstract bool IsReadyForSubmission();
protected class NotEnteredTimesheetStatus: TimesheetStatus
{
private const string DESCRIPTION = "NotEntered";
private const int ID = 0;
public override int Id
{
get { return ID; }
protected set { if (value != ID)throw new InvalidOperationException("ID for NotEnteredTimesheetStatus must be " + ID); }
}
public override string Description
{
get { return DESCRIPTION; }
protected set { if (value != DESCRIPTION)throw new InvalidOperationException("The description for NotEnteredTimesheetStatus must be " + DESCRIPTION); }
}
public override bool IsReadyForSubmission()
{
return false;
}
}
//etc
}