Is it bad practice to have public data objects? [duplicate] - java

This question already has answers here:
What is the use of encapsulation when I'm able to change the property values with setter methods?
(17 answers)
Closed 5 years ago.
One of NASA's coding rules for writing safety critical programs is:
Declare data objects at the smallest possible scope
My question is, what if I have a large data object that I would like to pass around. Should I parse the object to a smaller object whenever it goes out of scope (e.g. package-level)? What if it needs to be passed to multiple packages? Do I have to create a package-level object every time?
EDIT: To clarify, I was referring to POJOs, perhaps obtained by deserializing an API response. All this time I've been making POJO classes with public fields.

Clearly, if objects of a certain class must be manipulated in different packages then either the class itself or some interface it implements must have public visibility. But that doesn't mean you need to expose every little detail about the class to public scrutiny or interference. The rule is just saying that you should not, nay, must not, expose every little detail.
Obviously some details must be publicly visible or else the class wouldn't be too useful. But there are almost always some other details which are none of the public's business, and the rule is telling you that you need to identify which details are which and not make public those details which are, in fact, none of the public's business.
The rule also relates to scope of variable declarations: declare things in the smallest scope possible. For example, if you need a variable to hold onto a result temporarily, declare a local variable inside the method where it is needed:
// YES
public class C {
private void meth1(){
int x = ...
}
}
not an instance variable in the containing class:
// NO!
public class C {
private int x; // an even worse sin would have been to make x public
private void meth1() {
x = ...
}
}

Related

How to define a "good" get() method for a private variable in a class? [duplicate]

This question already has answers here:
Why make defensive copies in getters inside immutable classes?
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 3 years ago.
I'm learning Java and I have some doubts.
If defined a class with a private variable like
class test<A>{
private A var;
...
public A get(){
return var;
}
}
Is the get method wrong?
I think so because with this definition I can modify the variable "var" like
test<A> x = new test<A>();
A temp = x.get();
temp.set(*something*);
At the end x is changed (I tested it using Vector as A). If I understand correctly, this works because object reference (I miss C pointers, sob). Am I wrong? Maybe I don't understand the purpose of the keyword "private"! Thanks in advance!
Edit: I have no problems with "pass-by-reference" and "pass-by-value". I have doubts defining get() method for a private variable in a class (you don't say?). Please stop linking Is Java "pass-by-reference" or "pass-by-value"?
If your getter method is returning a reference to a mutable object, then this greatly weakens the quality of the encapsulation provided by your class, because it becomes possible to modify the state of an instance of your class without calling a method of the class.
One standard strategy to guard against this problem is what J. Bloch calls defensive copies (Effective Java, 3rd edition, Item 50: "Make defensive copies when needed").
This would mean creating a copy of var in the getter method, and returning that copy instead. How to do this depends on the design of A.
Because A is a type parameter, making a copy of the instance requires additional support in the design. To see how to achieve this using Java's cloning mechanism, see my answer to the post "Does it make sense to create a Copyable type interface instead of using Cloneable?".
If this is a problem, you can create a façade to protect your variable
public class Facade extends A {
A myObj;
public Facade (A obj) {
myObj =
}
public A get(){
return myObj.get();
}
public B set(Object val) {
throw new RuntimeException("Setting is not allowed");
}
}
This might be a bit too much detail for just starting, but you might review class java.util.concurrent.atomic.AtomicReference<V>, which is very similar to your example.
Generally speaking, placing instance variables in private variables, while providing access to the variable using a getter and a setter, is standard practice.
Note that your class name should be capitalized, type parameter 'V' is more standard, and the variable name would more usually be 'value'. Also, try to pick a more communicative name for the class. (Type parameter type variable could be 'ValueType', which would fit some preferences. But, single character type variable names are more usual.)
public class Wrapper<V> {
private V value;
public V get() {
return value;
}
public void set(V value) {
this.value = value;
}
}
I'd add some other point here: as others have said, you hand out the object reference and it can be modified, which could be bad.
Object orientation is about keeping the data and the code that works on it in one place. If you need getters, think what the callers of the getters need to do, and whether that action should rather be a method on the class that has the data. Your code could suffer from the Feature Envy code smell, as it violates the Tell, Don't Ask principle.
To fix this, remove the getter, and introduce new methods as needed. For example, if you have some data object that needs to get printed, you could pass the Printer to the object and have it print itself to the given Printer.
If you're dealing with a collection class (just a guess from your template parameter), you may need to keep the getter, but then you're probably not concerned with the caller changing the value anyway.

Objects Within Objects in Java

I've been given a coursework assignment where I have to build a prototype hotel booking system, in accordance with the specification, which is as follows:
You will need at least three classes:
Hotel
This should store all the essential information about a hotel,
including a name and some rooms.
Room
This should store the number of beds in a room.
Bed
This should store the size of a bed (i.e. single or double).
I'm totally confused about where to start!
I was under the impression that objects could not be contained within other objects.
For example, let's assume we instantiate a "Hotel" object. How would we then instantiate "Room" objects, and within that object, "Bed" objects?
How are these objects being stored? How do we interact with them indirectly, from another object?
Typically you don't need to nest classes into other classes, which are called inner classes, unless the work that a class takes care of can be chunked into small units that never need to be known outside it's parent class.
It sounds like the concept you want to look into is Composition. It's when an object holds a reference to another object.
public class Room {
private boolean isVacant;
public Room() {
isVacant = true; // The room starts vacant
}
// Pretend there is a way for clients to check in and out of the room
public boolean isVacant() {
return isVacant;
}
}
public class Hotel {
// Using composition, I can make an instance of one class
// available to the methods of another
private Room room101;
public Hotel(Room room101) {
this.room101 = room101;
}
public boolean isRoom101Vacant() {
return room101.isVacant();
}
}
Our hotel may not be very useful having only one room, but this example shows how you can "compose" one object into another. Methods of Hotel can now use methods of it's Room instance known as room101. You will want to think about how your rooms are structured, and how you want to represent it within your Hotel class. A few objects used to store collections of other objects include ArrayList and HashMap.
Edit:
this is a fairly difficult concept to understand before you understand what a class is compared to an instance of that class (an object). In the constructor of my sample Hotel class, I have a variable of type Room called room101. And outside of the constructor is an instance field of the same type and name.
Java will always refer to a variable or reference of the nearest scope. So if I have a method reference called room101, how can I refer to that other one declared outside the constructor, at instance level? That's where this comes in.
public class ThisExample {
// This is a separate variable at the instance level
// Lets call this global in the comments
private int a;
public ThisExample() {
// This is a separate variable in the method level,
// lets call this local in the comments
int a;
a = 5; // our local is now assigned 5
this.a = 10; // Our global is now assigned 10
this.a = a; // our global is now assigned to 5
a = this.a * 2; // our local is now assigned to 10
}
}
In short, this refers to "this" instance of a class. It's a way for an instance of a class to refer to itself as if from the outside. Just like how another object would refer to room101's method as room101.isVacant(). A method in the Room class would similarly do this.isVacant() for the same effect.
And as a final note, if there is only one declaration of a symbol within a class. The this keyword is implied. So Room can call it's own method just as well without it as long as there is no other conflicting symbols of the same name. (This doesn't occur with methods as much as with instance fields/local variables)
Hopefully this helps clear things up a bit!
Your assignment is how to model some real world concepts into code.
It appears that the core of your problem can be stated as a Guest can book a Room.
I don't want to do your work for you, so let me start by asking how you would write that in code? After that, we can address the "Hotel" and "Bed". Is this a major assignment or just a quick question? Your implementation would depend on this.
A rule to learn and apply is:
An action on an object in the real world, becomes a method of that object in an Object Oriented approach.

Accessing private fields within a class [duplicate]

This question already has answers here:
Private Member Access Java
(7 answers)
Closed 9 years ago.
I've encountered one interesting thing to me relating to the basics of Java.
Here's the code:
class Whoa {
private int n;
private void d() {
Whoa whoa = new Whoa();
whoa.n = 1;
}
}
Why the field n of object whoa is accessible? I mean, OK, we're in the class. But whoa is the separate object, I thought we have access only to the fields of a current object. Although I admit that if we have a method that takes a Whoa parameter:
private void b(Whoa w) {
w.n = 20;
}
we'll definitely have access to n. It's all quite confusing. Could anyone clarify this please?
The point of Java's access modifiers is protecting the internals of a class from code foreign to it. Since all instances of the same class share the same internal code, there would be little use in enforcing access restriction between them.
This the rationale of Java's class-level encapsulation.
As long as your are in the same class,you can access the private variables
For every new instance of the Object 'Whoa' that you create there will be an instance of 'n'. That 'n' can only be accessed from the instance of 'Whoa' (hence private)

Set, Get and Constructors in Java

Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.

How are instance methods stored [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java/C# method representation in memory
I was wondering if i have an object in java, how are it's instance methods stored? Does an object have a pointer to it's instance methods?
Example:
public class MyObject {
private int x;
private int y;
[..]
}
If i plan keeping a lot (A big tree of objects for example) of these MyObjects in memory, will it make a significant difference in memory terms if apart from a getter for x and for y i define an instance method calculating the sum?
I'm trying to sort out wether i should add more instance methods or doing the calculations in another class using the getters and setters.
The instance methods of an object are stored in its class object (only one copy should exist), they are not "copied" with each new instance, instead, under the hood each instance holds a reference to the method implementation residing in the class object.
For a technical explanation, take a look at this chapter from the book "Inside the Java Virtual Machine", in particular the "Object Representation" section; it details how each instance of an object references its methods in the corresponding class. Notice that the implementation details for this are not present in the JVM specification, and they're left open to the implementors - the linked document presents several strategies.
The object needs memory for its attributes (NOTE: for object, the attribute stored is a pointer to the real object, which lies elsewhere in memory). No additional memory is needed for methods (code) as they are stored with the class.
IE:
public class MyClass1 {
private int myNumber;
}
and
public class MyClass2 {
private int myNumber;
public int MyMethod1() {
}
public int MyMethod2() {
}
public int MyMethod3() {
}
....
public int MyMethod1000() {
}
}
use the same memory per instance.
They are stored inside the class. Details are in the JVM specification.
No it will not make a significant difference. The method is actually stored in the class definition file MyObject.class. There is only one instance of that method. It gets executed for each instance but is only defined once.
Each instance is associated to a class.
The class defines the methods for all instances.
Because of this, there is no need to have pointers to methods for each instance.
An instance just store the values of the non static attributes
If you want to know the class of an instance, you just use instance.getClass().
By using getClass() you can access the list of all methods at runtime.

Categories