Why declare variables private in a class? [closed] - java

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Folks I'll start by apologising as I'm sure this has been answered elsewhere - I just can't find an answer that explains it in a way I understand! I'm doing an MSc conversion course and there are some elementary basics that I'm still struggling with this, including this one - why making a variable private is better.
Say I have a Java class called Person, with a print method. I could create it and define it as such:
public class Person
{
public String name;
public String telephoneNumber;
public void print()
{
System.out.println(name + " " + telephoneNumber);
}
}
Then, in a main class, I could write the following code:
class testPerson
{
public static void main(String[] args)
{
Person test;
test = new Person();
test.name = "Mary";
test.telephoneNumber = "01234 567890";
test.print();
}
}
If I did this, the test.print(); would produce the output:
mary 01234 567890
However, I know this is considered poor coding. Variables should be private inside a public class, as we don't want to allow people to see how this information is stored or to be able to edit information without authorisation.
So now, I'll edit the Person class to declare the two Strings private and add get and set methods, like so:
private String name;
private String telephoneNumber;
public void setName (String name)
{
this.name = name;
}
public void getName()
{
return name;
}
// same code for telephone methods.
Now, in the main class, I would change the methods of setting name and telephone to the following:
mary.setName("Mary");
mary.settelephoneNumber("01234 567890");
According to the lecture notes I'm following, this is more efficient (although could be made even more efficient by adding in a Person() method to allow for instantiation etc.)
However, I'm struggling to see why this is better.
In the former method of doing things, the user could directly access the variables. But even though by hiding the variables they can't directly access them, the user can indirectly access and modify them which produces the exact same outcome.
Why is it that this is preferred and what no doubt silly thing am I missing/overlooking?

Pizza Delivery Analogy
You order a Pizza for delivery.
Pizza boy knocks the door and expects you to pay for it.
You take out the money from your purse and hand it over to the delivery boy. (You are in control of hiding the internal details (drivers license etc.)) Alternatively,
You could hand over the purse to the delivery boy and ask him to take the money from it. By doing this you are no longer in control. You are exposing internal details.
Read about Information Hiding and Encapsulation is not information hiding.

It's not that it's more efficient, it's that it's more maintainable and a good practice.
For example, with setter methods, you could have your setTelephoneNumber actually check that the String is a valid telephone number before you actually do the setting. You couldn't possibly do that if you made the variable public. Using a setter from the very beginning means that you can go back and e.g. add validation later on, whereas if you had made the variable public, you would have to add a setter and modify all your users everywhere to use the setter instead of modifying the variable directly.

People will give you a million regurgitated reasons why it is better, but it is only better in some cases, not in all of them unequivocally. For example, take Java's own class GridBagConstraints—it has no methods at all (if you don't count clone, which it has anyway; all Java classes inherit it from Object). Why? Because there's a case where this is in fact more practical. And GridBagConstraints is a Java Bean in the purest sense: it's all about properties, no business logic there.
Let me report on another fact from practice: no setter ever validates its input; no getter ever calculates its result. In the world of JavaBeans, any such behavior will soon get in the way of the universal assumption that setters set, and getters get. Basically, if you diverge in any way from the exact equivalent of public fields, you lose.
The modern Java APIs, like Hibernate, acknowledge this fact by accepting naked public fields on an equal footing with JavaBean-style properties. Earlier versions didn't allow that, but as experience with Java accrues, the realization is finally dawning that public fields are OK.

You have to operate on the assumption that, at some point, someone else will use your code - and that someone else could be you, a year down the line. If you see a public property on a class, you should be able to assume that it's free for you to manipulate, if it's not to be directly modified you shouldn't be able to see it externally.
A good literal example would be the dimensions of a bitmap object. Most machines wouldn't like it if you tried to draw a bitmap of dimensions -10x-10, because such a thing would obviously be impossible to represent on a screen. If the width/height properties of this bitmap were simply public variables, it's possible they might be set to invalid values later on by a well-meaning coder (NEVER assume that it wouldn't happen), and when it came to render it - bang, you've got a frozen computer.
By hiding the variables and using a setter, you can prevent this ever happening:
private int _width = 10;
public void setWidth(int value)
{
//Prevent the value moving into invalid range:
if(value < 1)
value = 1;
if(value > 4096)
value = 4096;
//Now apply it
_width = value;
}
However, for speed and convenience you don't have to develop your code like this at first - just make sure you go through it afterward and hide what you need to!

there are also security issues to consider. a common example is a bank account. you have a balance, and you use deposit to put in money, and withdrawal to remove money. if balance was public, it could be modified without depositing or withdrawing money. that could be VERY bad.
within a method, you can put checks on things, such as making sure you don't take more money out of an account than actually exists. you can't really do that if you're accessing the values directly. it's about control.

Related

Need Example of Poor Encapsulation [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to see an example of reaching directly into the code from a class that uses publicly declared data members to see an example of poor encapsulation so I can understand the good examples of encapsulation in OOP by contrasting with a bad example.(Being told to use encapsulation without a bad example is like being told not to steal without understanding what stealing is to me.) Thanks.
Suppose you have a Counter class that:
Starts with value = 0
Lets you increase the value by one (increment)
Lets you see the current value
A poorly-encapsulated version would directly expose the inner counter value:
class Counter {
public int value;
public Counter() {
this.value = 0;
}
public int increment() {
return ++this.value;
}
}
The problem, of course, is that users of the class can do this:
Counter c = new Counter();
System.out.println(c.value); // 0
c.increment();
System.out.println(c.value); // 1
c.value = 42;
System.out.println(c.value); // 42
Proper encapsulation corrects that:
class Counter {
private int value; // *** Private
public Counter() {
this.value = 0;
}
public int increment() {
return ++this.value;
}
public int getValue() { // *** Accessor
return this.value;
}
}
Now, there's no way¹ for the user of the class to directly set value.
Counter c = new Counter();
System.out.println(c.getValue()); // 0
c.increment();
System.out.println(c.getValue()); // 1
// No equivalent to `c.value = 42` is possible here¹
¹ (without using reflection)
Your question is a useful one, since understanding the reasons that encapsulation is important will help you avoid overgeneralizing the principle as well as help you understand when you've done it adequately.
You can find an example of poor encapsulation here: https://github.com/dotnet/training-tutorials/blob/master/content/csharp/getting-started/encapsulation-oop.md When the class in the example is used by other code to do something mundane, it create problems because the class hasn't been encapsulated. (Other examples might illustrate the problems that are created by poor encapsulation rather than a lack of encapsulation, but I understand you to want an example of the basic idea.)
Many times the problem that is created by not encapsulating your code is that properties and/or objects are updated or deleted when it is a copy of the object that you actually wish to update or delete.
Here are some relevant portions of the linked example. The first quote describes the problem that is created when the class lacks encapsulation:
Notice that in this example, the technique used to print the orders is a while loop that throws away each record as it prints it. This is an implementation detail, and if the collection this loop was working with were properly encapsulated, it wouldn't cause any issues. Unfortunately, even though a locally scoped orders variable is used to represent the collection, the calls to RemoveAt are actually removing records from the underlying Customer object. At the end of the program, both customers have 0 orders. This is not the intended behavior.
The second quote notes that the problem can be "solved" with a different implementation, but avoided altogether with encapsulation:
There are a variety of ways this can be addressed, the simplest of which is to change the while loop to a foreach, but the underlying problem is that Customer isn't encapsulating its Orders property in any way. Even if it didn't allow other classes to set the property, the List type it exposes is itself breaking encapsulation, and allowing collaborators to arbitrarily Remove or even Clear the contents of the collection.
What this example illustrates well is that the need for encapsulation isn't absolute, but it's most certainly a best practice.

Understanding Encapsulation in OOP with code

Trying to understand the concept of encapsulation, I came across this definition "Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible".
But practicing the same, I am not sure which of the following code is more apt for OOP:
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = value * value;
return this.square;
}
}
or
public class Square {
//private attribute
private int square;
//public interface
public int getSquare(int value) {
this.square = calculateSquare(value);
return this.square;
}
//private implementation
private int calculateSquare(int value) {
return value * value;
}
}
Combining the attributes and methods in the same entity in such a way as to hide what should be hidden and make visible what is intended to be visible
This is a potentially misleading statement. You are NOT hiding anything from anyone. It is also not about methods or fields. Unfortunately this is the way things are worded in almost every place.
How
When writing any piece of program, (be it a function, class, module, or library) we think of the piece we are working on as my code, every other code as my client code. Now assume that all the client code is written by someone else, NOT you. You write just this code. Just assume this, even if you are the only one person working on the entire project.
Now the client code needs to interact with my code. So my code should be nice and decent to talk to. The concept of encapsulation says, that I partition my code in two parts, (1) that the client code should be bothered with, (2) that the client code should NOT be bothered with. The OO way of achieving encapsulation is by using keywords like public and private. The non OO way of achieving this is naming convention like leading underscores. Remember, you are not hiding, you are just marking it as none-of-your-business.
Why
So why should we encapsulate things? What should be organize my code into public and private regions? When someone uses my code, they are of-course using the whole thing, not just public thing, so how come private is something that is none-of-their-business? Note here words like someone and their could refer to yourself - but only while working on the other piece of code.
The answer is easy testability and maintainability. A complete project if tested exhaustively, can be quite a task. So at minimum, when you are done coding, you just test the public aspects of my code. You do not test any of the client code, you do not test any of the private aspects of my code. This reduces test effort while preserving sufficient coverage.
Another aspect is maintainability. My code will NEVER be perfect, it WILL need revisions. Either because of bugfix or enhancement, my code will need tinkering. So when a new version of my code is available, how much is client code impacted? None, if changes are in private regions. Also, while planning a change, we try to confine it as much as possible in private regions. So the change, from client's perspective becomes a no-impact. A change in public aspects of my code, will almost always require changes in client code, now that will need testing. While planning the big picture of my code, we try to maximize the area under private regions and minimize the area under public regions.
And more
The idea of encapsulating links with the idea of abstracting which in turn links with idea of polymorphism. None of these are strictly about OO. Even in non OO world like C or even Assembly, these apply. The way to achieve these differ. Even this applies to things beyond computers.
The process of sewage management, for example, is
encapsulated within the public interface of drains. The general public bothers only with the drains. The treatment, the disposal, the recycling are none of general public's business. Thus, the sewage management could be treated as an -
abstract entity - an interface with just the drains. Different government and companies implement this in their own way. Now an city may have a permanent system of sewage management, or it can periodically -
switch providers. In fifty years of government operation, the situation was bad, but once they contracted that BigCorp Inc, now people can breathe free. We just did polymorphism. We switched implementations, keeping the public interface same. Both government and the BigCorp Inc use the same drains, but their own processing facilities, which are encapsulated away and polymorphically switchable.
In your code
In both your codes you chose to encapsulate the storage, the field is made private. This is a nice approach and certainly OO way. In both of your codes, the algorithm is also encapsulated - i.e not visible to the client. Nice. In your second code, you went ahead and extracted the algorithm in a separate non-public method. This is commendable approach, although obviously an overkill for doing something trivial. Better OO none the less.
What you did in second code even has a name: the strategy pattern. Even though here it is useless (and overkill), it could be useful in a scenario when let say you are dealing with extremely large numbers, such that calculating their squares take very long time. In such a scenario, you could make your calculateSquare method protected, have a class FastButApproxSquare extends Square, and override the calculateSquare method with a different algo which calculates an approx value much faster. This way you could do Polymorphism. Whoever needs exact value will use the Square class. Whoever needs approx value will use FastButApproxSquare class.
Encapsulation is about hiding implementation and structure details from client code. In addition it is about coherence: keep things close together which are highly related to each other.
For example consider a class which manages players of a football team:
public class FootballTeam {
public final List<Player> players = new ArrayList<>();
}
Client code would have access to the list of players, to look them up, to add players and so on:
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.players.add(player);
}
public void firePlayer(int jerseyNo) {
Optional<Player> player = team.players.stream()
.filter(p -> p.getJerseyNo() == jerseyNo)
.findFirst();
player.ifPresent(p -> team.players.remove(p));
}
}
Now, if someone decides to change the field FootballTeam.players into a Map<Integer, Player>, mapping the players jersey number to the player, the client code would break.
In addition the client code deals with aspects / features closely related to a player. To protect the client code and to ensure changeability of the FootballTeam implementation hide all implementation details, keep player related functionality close to the structure, representing the team and reduce the public interface surface:
public class FootballTeam {
private final Map<Integer, Player> players = new HashMap<>();
public void addPlayer(Player player) {
players.put(player.getJerseyNo(), player);
}
public Optional<Player> lookupPlayer(int jerseyNo) {
return Optional.ofNullable(players.get(jerseyNo));
}
public void remove(Player player) {
players.remove(player.getJerseyNo());
}
}
public class FootballManager {
private final FootballTeam team = new FootballTeam();
public void hirePlayer(Player player) {
team.addPlayer(player);
}
public void firePlayer(int jerseyNo) {
team.lookupPlayer(jerseyNo)
.ifPresent(player -> team.remove(player));
}
}
If any code serves the purpose of encapsulation then that code is correct. The purpose of encapsulation is to provide a process of hiding the variables from other classes (i.e. by making the variable as private) and also to provide a way for other classes to access and modify the variables. Both of your code serves this purpose correctly.
If you would have used "calculateSquare(int value)" method as "public" then there would have been a problem. Other class could call this method directly without using set/get method. So as far as your this method is "private" I think both the codes are all right.

Classes with "Setters" and "Getters" only - advantages [duplicate]

This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 7 years ago.
I've had often the case that an API defines a class which only consists of its fields with the appropriated setters and getters.
However, they have had a specific role. So from a real life (OOP) point of view they actually were meaningful. The last time I've stumbled about this was the schema in Olingo. It's used to set a few properties.
My question is, is there any advantage over "just setting variables" from a technical point of view or are these classes only used to stick to OOP (and have clean code and so on)?
Edit: Please note that I'm not asking why we are using "Setters" and "Getters". Try to look at it from another perspective. Let's say you have to define three Strings to use them further in your code. Instead of defining them as "on the fly" private Strings, you decide to create a class storing these three strings as fields and defining setters and getters for them. Is there any technical advantage to do so?
Sample code for "schema":
public List<Schema> getSchemas() throws ODataException {
List<Schema> schemas = new ArrayList<Schema>();
Schema schema = new Schema();
schema.setNamespace(NAMESPACE);
List<EntityType> entityTypes = new ArrayList<EntityType>();
entityTypes.add(getEntityType(ENTITY_TYPE_1_1));
entityTypes.add(getEntityType(ENTITY_TYPE_1_2));
schema.setEntityTypes(entityTypes);
List<ComplexType> complexTypes = new ArrayList<ComplexType>();
complexTypes.add(getComplexType(COMPLEX_TYPE));
schema.setComplexTypes(complexTypes);
List<Association> associations = new ArrayList<Association>();
associations.add(getAssociation(ASSOCIATION_CAR_MANUFACTURER));
schema.setAssociations(associations);
List<EntityContainer> entityContainers = new ArrayList<EntityContainer>();
EntityContainer entityContainer = new EntityContainer();
entityContainer.setName(ENTITY_CONTAINER).setDefaultEntityContainer(true);
List<EntitySet> entitySets = new ArrayList<EntitySet>();
entitySets.add(getEntitySet(ENTITY_CONTAINER, ENTITY_SET_NAME_CARS));
entitySets.add(getEntitySet(ENTITY_CONTAINER, ENTITY_SET_NAME_MANUFACTURERS));
entityContainer.setEntitySets(entitySets);
List<AssociationSet> associationSets = new ArrayList<AssociationSet>();
associationSets.add(getAssociationSet(ENTITY_CONTAINER, ASSOCIATION_CAR_MANUFACTURER, ENTITY_SET_NAME_MANUFACTURERS, ROLE_1_2));
entityContainer.setAssociationSets(associationSets);
entityContainers.add(entityContainer);
schema.setEntityContainers(entityContainers);
schemas.add(schema);
return schemas;
}
Added an example which contains exactly the content I'm questioning. Consider the class "test" as a class which contains two fields "a" and "b" and the appropriated "setters" and "getters".
Simple example:
public class Main {
public static void main(String[] args) {
//Version 1: Common practice
test asdf = new test();
asdf.setA("asdf");
asdf.setB("asdf2");
//Doing something with "asdf" and "asdf2"
//Version 2: My request
String a = "asdf";
String b = "asdf2";
//Doing something with "asdf" and "asdf2"
}
}
There are lots of real-world practical advantages to getters/setters:
If you need to add logic to them (usually a setter), you can do so without breaking your API.
When debugging, if you need to know when a field is changed, you can set a breakpoint in the setter.
You can use an interface to define your API.
Subclasses can add logic to them.
If appropriate, the exposed type of the getter/setter can be a more generic or limited version of the actual field being used (for instance, a getter can be a read-only List), allowing you to change the implementation (perhaps an ArrayList becomes a LinkedList) without, again, breaking your API.
They can be proxied for testing.
In theory, the real-world, practical disadvantage is that you're making method calls rather than just setting fields. But if it's important from a performance standpoint, the JVM's just-in-time optimizing compiler will inline simple getters/setters.
Definitely there are advantage.
With this setter and getter you allowing other to access you property when you monitoring.
Which I mean, You are giving a controlled access. You can filter and check the value that other object setting to the fields.
It is useful to have methods to access and set the attributes (consistency check, encapsulation...), but it is boilerplate having to do it explicitly when the getter/setter has the default action.
Many languages now use myObject.attr as the only syntax, be it for attributes or getters. Default getters and setters are automatically (and silently) generated if the attributes are visible. Scala is one of those languages and to me, that's the best solution.
With Setters , we can abstract away the logic for setting the variable.
For Ex : Minimum Balance can't be negative. If we use the variable directly to set the balance, we may set it to negative value by mistake. This can be avoided with the setters.
public Class Account {
public int minBalance;
public void setMinBalance(int amount) {
if(amount < 0) minBalance = 0;
else minBalance = amount;
}
}

Design Pattern in real world [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am learning design pattern from Head first book and I understood most of them. But when I try to apply in real world, it becomes more difficult. In every example, it has created lot of sub classes. But do we really create so much classes in real time projects?
E.g. Consider an example of Bank Account
Approach 1:
Account {
String name;
double balance;
operation1() {
}
}
SavingAccount extends Account {
// some extra fields and methods related to saving account
operation1() {
}
}
CurrentAccount extends Account {
// Some extra fields and methods related to current account.
operation1() {
}
}
When I map these classes with database, using Hibernate using one of the inheritance strategy, e.g. table per sub class, I will end up with three tables. Account, Saving_account and Current_account.
Advantage: I can call operation1() depending on the type of object using polymorphism.
Disadvantage: more tables and classes. If project is more complex and big, It will end up with thousands of classes.
Approach 2:
Account {
string name;
double balance;
string type;
operation1() {
}
}
I need only 1 table for this approach called Account. And "type" field will identify the type of the account.
Advantage: Only 1 table and class.
Disadvantage: I will lose Object oriented world and every place I have to put the condition as below.
if (type == saving) {
// do this;
} else if (type == current) {
// do that;
}
As per theory, approach 1 is correct and best. But currently in my project, approach 2 is used. My project is not banking. I took it as an example for the simplicity.
I know this is very basic question. But due to my current project implementation, I could not stop myself asking this question.
EDIT: maintainability of approach 1 is more better than approach 2.
Design patterns like inheritance are difficult to describe in terms of their importance, because it takes a very large project to realize the power of it. Usually examples end up with stuff like:
class A {
}
class B extends A {
}
class C extends B {
}
class D extends A {
}
And then you get a lot of not so real life questions like which method foo() really refers to when it's implemented four separate times.
The motivation for using inheritance is to group similar types of things together in a class. A basic example is if you want to have a bunch of different objects all in a list together. This isn't possible if they're all different types, but if they're in an inheritance hierarchy, you can group them all together.
For your example, you can put every Account object into a single list, no matter which subclass the objects are really in.
List<Account> list = new ArrayList<Account> ();
list.add(new Account());
list.add(new SavingsAccount());
list.add(new CurrentAccount());
Say you want to process every thing in that list. If you have one common method, you can use polymorphism to make each Account do its own specific action:
for(Account a : list) {
a.operation1();
}
Much simpler than having a separate list for each type of object, no? And then if you want to make more types of accounts, if you extend the base Account class, you don't have to add new lists and new loops to your code. Everything can remain as is.
Using inheritance also helps to use code that other people have written. If you want to add something to a class that someone else has written, you can include it in a package and then extend it with one of your own classes. That way you don't have to do a lot of copy and pasting and navigating through the other class's source code. You also can extend another class even if you only have its .class file, rather than the source code in a .java file.
So the power of inheritance depends on how you use it. In a small example, it doesn't really make sense. But the bigger the project, the more it makes sense.
Both approaches are valid as you just mentioned and the pros and cons you explained are also valid.
But for example you if you are Giving this Accounting package (compiled jar) as a library to be extended by other people, the approach 1 is ideal because;
You don't need to modify any source code of Account, just extend it and then implement your own version. Ex:- FixedDepositAccount
Won't break your Account code.
No need of Testing again for Account.operation1()
But if you are willing to share the source code and willing to do above mentioned steps then it is best to use method 2.
In Java we can have String type; (not string type;), but even better would be an Enum type (that way we could have add a Money Market Account or a Platinum Preferred Savings Account, possibly without re-implementing the caller code). Something like,
enum AccountType {
CHECKING(0.005), SAVINGS(0.01), MMA(0.02);
final double rate;
private AccountType(double rate) {
this.rate = rate;
}
public double getRate() {
return this.rate;
}
}
And with an AccountType you can safely use == for equality, while doing if (type == saving) { with a String is asking for trouble. That is
if (type == AccountType.CHECKING) {
} else if (type == AccountType.SAVINGS) {
will function as you would expect. Finally, it would be better to try and avoid the if chains and instead encapsulate whatever you plan to do with the account type into the enum itself when you can. For example,
Account acct = getAccount(accountNumber);
if (acct != null && acct.isValid()) {
acct.balance += acct.balance * type.getRate();
}

Proper way of getting variable from another class

I can call variables 2 ways.
One is just to do it like this:
MyClass myClass = new MyClass();
myLocalVar = myClass.myVarVal;
And the other way is to use a getter like this:
myLocalVar = myClass.getMyVarVal();
Both ways are working fine, but I was wondering what would be the most efficient/proper way of doing this?
Thanks
Both techniques are terrible, but using the getter is the common (and safer) practice.
In order to access a public data member (a.k.a. public field or public property) of a class, you must know the implementation details of the class (the data member name and the data member type). This is a bad thing; it breaks the OOP concept "information hiding" and increases "coupling".
Using a getter is also bad (as in a bad OOP practice) because objects are not just wrappers around data; objects are supposed to encapsulate functionality and data. "store this here value so I can get it later" is not functionality; it is hoot functionality (as in a monkey in a cage hooting). Getters are; however, an accepted practice in java (and other OOP-lite languages like c++ and c#).
Lest you think I am some ivory tower purest, of course I use getters; I use java, so I use getters.
Getters are fine for getting the work done (no pun), just don't walk around believing that "I R gud OOP Prgmr", because if you use getters you are not a "good oop programmer", you are just a programmer who gets work done.
Edit: Perhaps a better way.
The better way is to not use getters, but to instead design your classes so they expose functionality not data. In practice, there is a point where this breaks down; for example, if you need to display an address on a JSP page, you put a bean in the request (or session or blah) with the address and expose the values using getters. A "more oop pure" way would be to put a bean that exposed "display the address on a jsp" functionality.
Edit2: Perhaps a better example.
Say I work for a phone company, in the USA, and I have an object that represents a customers phone number. This might look like the following:
public class CustomerPhoneNumber
{
private String npa; // numbering plan area (google search nanp for more details)
private String nxx; // exchange.
private String serviceNumber;
public String toString()
{
return "(" + npa + ") " + nxx + "-" + serviceNumber;
}
public boolean equals(Object object)
{
... standard equals implementation (assume this works)
}
}
Now say I get a phone number as an input from a web page in the form String inputPhoneNumber. For the purposes of discussion, the class that receives this input is called "the servlet".
How can I answer this question: "Is the input phone number in my list of CustomerPhoneNumber objects?"
Option 1 is make the npa, nxx, and serviceNumber data members public and access them. This is terrible.
Option 2 is provide getters for npa, nxx, and service number and compare them with the input. Also terrible, too many internal details exposed.
Option 3 is provide a getter that returns the formatted phone number (I called this toString() above). This is smarter but still terrible because the servlet has to know the format that will be used by the getter and ensure that the input is formatted the same way.
Option 4 (I call this "Welcome to OOP") provide a method that takes a String and returns true if that matches the customer service number. This is better and might look like this (the name is long, but sufficient for this example):
public boolean doesPhoneNumberMatchThisInput(final String input)
{
String formattedInput;
String formattedCustomerPhoneNumber = npa + nxx + serviceNumber;
formattedInput = ... strip all non-digits from input.
return StringUtils.equals(formattedCustomerPhoneNumber, formattedInput);
}
This is the winner because no implementation details are exposed. Also the toString can be used to output the phone number on a JSP page.
StringUtils is part of Apache Commons Lang.
For the sake of encapsulation you should always go with the second alternative.
myLocalVar = myClass.getMyVarVal();
Efficiency wise you most likely won't notice a difference.
Do ALWAYS use getter and setter to access your properties!
You should also take a look at this.
myClass.getMyVarVal() is slower since it is a method call and so it creates entrance on the stack for return value, etc. But it is better OOP practice to use getters.
Just create object and object.variablename; or object.methodName(); can be used to make non-static reference...no use of getter is required.
myLocalVar = myClass.getMyVarVal();
it will be good to use it if you are working with OOP concept
Tomcat + Heroku + Maven project:
How to reference Main class static variable:
HEROKU_PRJ_FOLDER\src\main\java\servlet\HelloServlet.java:
import launch.Main;
String my_str = Main.TEST_STRING;
HEROKU_PRJ_FOLDER\src\main\java\launch\Main.java
package launch;
....other imports here....
public class Main {
public static final String
TEST_STRING = "[TEST_STRING]";
public static void main(String[] args){
...somelogic...
};
};
This will probably work for any Tomcat project,
but I did this using Tomcat+Heroku+Maven. Posted answer because
the closest question I could find was this, which I already knew
how to do, just the exact import paths I found a bit confusing for
my particular problem.

Categories