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 9 years ago.
Improve this question
I am very new to programming. Can anyone explain why data hiding is done in any oop language? If the client cannot view/change my code why do I need to hide data. I'll never display or use that data. What warrants hiding?
It is about complexity. Take your car's engine for example. It is a very complex object. You can, if you know enough get in there and twiddle with stuff and operate the car. However, this would be very dangerous. You can maybe do things that the engine designer did not intend.
In this crazy scenario you are given an interface. That is the driver's position with the steering wheel, gears, pedals etc. In that position the things you can do are restricted, and safe, and driving the car is easy. For instance, you cannot change the gear out of park without first stepping on the brake pedal. If I bypass the interface and go directly into the engine I would probably be able to do anything even if it leads to the destruction of the engine.
To apply this to software consider if you have a Fraction class that is made up of 2 integer values: a numerator and a denominator. There is a class invariant ( a rule) that says: denominator cannot be 0. If the denominator did happen to be 0 then the Fraction object will make no sense and will be useless. In the following code I am not hiding the variables:
public class Fraction{
int numerator;
int denominator;
public Fraction add(Fraction f){
//add this Fraction to f
}
....
}
In this case the client code can do this:
Fraction f1 = new Fraction();
f1.numerator = 2;
f1.denominator = 0;
Fraction f2 = new Fraction();
f2.numerator = 3;
f2.denominator = 4;
Fraction f3 = f1.add(f2);
What does your add method do here? What this code does is give the responsibility of ensuring that such problems are avoided to the client. With proper encapsulation the responsibility of ensuring that all objects are constructed with integrity belongs to the class itself.
public class Fraction{
private int numerator;
private int denominator;
public void setDenominator(int d) throws IllegalArgumentException{
if(d == 0){
throw new IllegalArgumentExcepton("Denominator cannot be 0");
}
this.denominator = d;
}
...
}
If the client tries to do this:
Fraction f1 = new Fraction();
f1.setDenominator(0); ///exception
And everyone is safe.
So to summarize:
Makes your objects safe - client cannot do things that you did not intend
Makes your objects easier to use - client does not need to know all the inner workings of the class to use it
contributes to the reusability of your code - if you decide to change the implementation of the class, as long as you do not change the interface then the clients are not affected.
This seems like a pretty broad question covering wides swaths of consideration but I'll try to address a couple items:
Sure your client may not be able to see or change your code (if you provide a complete compiled application) but you and any other maintainers can. The purpose of data hiding is to minimize the points-of-interaction between data and each level of an interface. This helps you to write and maintain correct code.
For the same reason that global variables can be extremely hard to use and maintain in a correct way, the more you localize use of data the easier it is to grok the code and be confident of correctness.
When you provide an abstract interface to a class you allow the class to operate on its internal data/state without the outside world needing to know anything about the underlying data structure, types, or algorithms used. This then makes your code much simpler for clients to use effectively.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
In terms of best practices, suppose I have this code:
public class ClassObject {
private int someNumber;
public void setSomeNumber(int x){
this.someNumber = x;
}
public int getSomeNumber(int x){
return this.someNumber;
}
//Should I even use this?
public void decreaseSomeNumber(){
--this.someNumber;
}
}
public void doSomeStuff(ClassObject instance){
// do some things
instance.decreaseSomeNumber(); //A
instance.setSomeNumber(instance.getSomeNumber() - 1); //B
}
I am wondering if either lines A or B are code smells. I think decreaseSomeNumber() is likely a redundant/useless function since I can just do instance.setSomeNumber(instance.getSomeNumber() - 1); everwhere.
On the other hand, it seems slightly more verbose doing instance.setSomeNumber(instance.getSomeNumber() - 1). What is the cleanest and good code design between A and B?
If you have a multithreaded environment, having (A) a decreaseSomeNumber method is worth it, however, you should make it threadsafe. Otherwise (B) two parallel threads might try to decrease the value at the same time, resulting in just a single decrease operation if they overlap.
That being said, it's typically hard work to really make code threadsafe, and in simple cases, occasional glitches might not matter. However, occasional is the keyword here: If you ever run into these, reproducing the problem will be horribly hard.
In terms of best practises you must avoid when is possible the form
public void decreaseSomeNumber(){
--this.someNumber;
}
and prefer the standard getters and setters.
But in some cases you need to decrease the value of a variable,
if this thing is occasional is good to use getters and setters
instance.setSomeNumber(instance.getSomeNumber() - 1);
instead in the case you need decreasing the a variable repeatedly (ex. A withdraw in a bank account) using only one method is not bad, but it must be defined like
public void decreaseSomeNumber(int many){
this.someNumber -= many;
}
in this way you are making a code more reusable, and this is good
P.S. the B way is more simple to syncronize in multi-threading enviroments
I would say it depends on more specific details, but I would be probably in favour of decreaseSomething.
With the getter and setter, you implicitly assume that:
The user of the API implements some (albeit trivial) computation.
The computation is performed at the time of the request.
The caller handles to concurrency-related issues on their own.
The (1) is rather a philosophical problem, although it might lead to errors caused by inadvertence, like calling get and set on two different objects.
The (2) can be a practical problem. Maybe you want to use the object from multiple threads. And maybe you don't need the number often, but you need to change it often. I believe that one could come up with some optimizations based on LongAdder or LongAccumulator or AtomicInt, which can optimize some highly concurrent places. With decreaseSomething, you can do it inside the class implementation. With getters and setters, you would need to somehow replace all occurences of x.setSomething(x.getSomething() + 1) by something else. That does not look like a proper encapsulation…
The (3) depends on your objective. Some people just make thread-unsafe code and claim it is programmer's responsibility to handle locks where needed, which can be OK. Sometimes, there might be a demand for thread-safe code. With getter and setter, you would need to use some locking scheme every time you access the data (which also makes (1) a less philosophical issue). Sometimes, it can be awful. Sometimes, it can be OK, because the caller wants to lock something more than just this one object.
As mentioned on the start of the post, I don't say I would prefer it every time. Maybe there are some cases when I would not go this way.
Edited
I would recommend changing this class as follows:
public class ClassObject {
private final int someNumber;
public ClassObject(int someNumber) {
this.someNumber = someNumber;
}
public int getSomeNumber() {
return someNumber;
}
public ClassObject decreaseSomeNumber() {
return new ClassObject(someNumber - 1);
}
public void doSomeStuff(ClassObject instance) {
//New ClassObject with new someNumber(instance's someNumber is decreased one unit)
ClassObject decreasedNumberClassObject = instance.decreaseSomeNumber();
}
}
I mean, if you wanna make a change in the Class properties(decrease, increase, multiply,...), it must return you, new Object(from the same Class), with the new property.
This code completely follows OOP paradigms. It is thread-safe, immutable and software(code) maintenance will be very high with the help of this approach.
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.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am wondering, mostly as an industry standard approach, or as a explicitly best practice approach how would one usually program if conditionals.
I find myself using the first approach below very often, never truly had a problem with it. But I'm still wondering when should either be used.
This is just an example to illustrate what I mean, it shouldn't be taken as the normal complexity of the comparisons usually utilized.
Example
public class Validation {
int x = 5,
y = 10,
z = 100,
a = 1;
public void compare() {
if (x < y) {
// Do Something
if (y < z) {
// Do Something
if (z < a) {
System.out.println("Whatever");
}
}
}
}
public void alternate() {
if (compareNumbers(x, y)) {
// Do something
if (compareNumbers(y, z)) {
// Do something
if (compareNumbers(z, a)) {
System.out.println("Whatever");
}
}
}
}
public boolean compareNumbers(int a, int b) {
return a < b;
}
}
Which one of those would be better practice? This being a super simple example, imagining you would normally use more complex validations.
And if 'alternate' is better, how many times would the comparison method/function have to be called for it to be better?
I am sorry if this belongs in StackExchange, I wasn't very sure of which one to post it in.
To narrow the scope to StackOverflow lets say this question applies exclusively to Java. Although a general programming view/response would be appreciated.
Extracting code to methods has several advantages:
It makes the code readable
It allows for easily changing the implementation of the method
It allows for unit testing of this specific method
If all your method does is to apply the < operator to the two arguments, I'd say none of the three reasons above apply, and that you're over-complicating things.
Just use the < method, and refactor your code once you need to apply a test with some more "meat" to it.
There are no "industry standards" for this kind of thing. For good reason.
As far as whether a < b is better that compareNumbers(a, b) ... the answer depends on the actual context.
In your example, most people would agree that a < b is better1. But this is an artificial example, and the answer could be different for other (more realistic) examples.
The same goes for all sorts of other questions about the best way to express algorithms, etc in code. It is rare for questions like this to have a single objectively correct answer. It is typically a matter of opinion ... and the context really matters.
But the bottom line is that the only real "industry standard" here is:
Use your professional knowledge, skills and judgement.
... and that means things like:
thinking about each particular problem and finding an appropriate (justifiable) solution,
considering coding effort, readability2, reliability, maintainability for your solution,
considering the economics of the situation; i.e. there is a trade-off between time spent "polishing" your code and time spent doing other things like implementing functionality, testing, writing documentation, meeting deadlines.
1 - If I have to scroll down a couple of pages to check what compareNumbers is doing, this is an impediment ... compared with an inline comparison using <. Now if there was some deeper semantic behind the comparison, then method abstraction could be a good thing, especially if there were comments in the method that explained the semantics. But in this example, compareNumbers(a, b) is less semantically meaningful than a < b.
2 - Another answer states (without supporting evidence) that abstracting code to methods improves readability. This is a gross over-simplification, and often it is demonstrably false. It is important technique ... but not always the right one.
From my personal experience I would use the original compare if I know the conditions are always going to stay the same, however I would use the alternate if there were even the slightest chance of needing to change the conditions. That way I wouldn't have to go back and replace every single condition individually.
To build upon breaking out the methods, I know your example is just that, a quick example, but rather than focus on the evaluation I would focus on the task and organize the code like this:
public void someMethodThatCares(int x, int y, int z, int a)
{
taskXY(x, y);
}
public void taskXY(int x, int y)
{
if (x < y)
{
taskYZ(y, z);
}
}
public void taskYZ(int y, int z)
{
if (y < z)
{
taskZA(z, a);
}
}
public void taskZA(int z, int a)
{
if (z < a)
{
}
}
Now you can build your dependencies as you need them, test each piece of functionality independently, maintain the logic in a clean fashion, and reuse it as needed.
Actually, I focus on the complexity of the code and the importance of that logic in my project. therefore, I might use all alternatives in the same class or even in the same method.
I would suggest reading Design Patterns by the Gang of Four for more information on how to decide. For every problem the approach would be different. For example if you needed to write multiple programs that individually checked each variable, the first program doing a less than check, the second doing a greater than check, the third doing a equals check it may make sense to use the Strategy Design Pattern for each of these cases to prevent the need to create multiple programs and using a Factory creator to decide which Strategy to use. The factory pattern could decide which one to use at run time based on user input or some other method.
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();
}
Let me start by saying, I am new to Java programming. I have coded something out that performs in the manner that I want it to. However, it is not very well written.
Here is my code:
import java.lang.Math;
public class Advisor_Score {
public static void main(String[] args){
double p1_1[] = {101,1,1,1.5,.5};
double p1_2[] = {101,2,2.5,2,4};
double p2_1[] = {102,1,5,5,5,5,5,5,5};
double p2_2[] = {102,2,2,5,3,4,5,1.5,2.5,5};
//These arrays represent individual users. The first value in the array is their customer number and the second is domain.
double All_users[][]={p1_1,p1_2,p2_1,p2_2};
//This is a 2-dimensional array takes into account all users.
double[] sum = new double[All_users.length];
double[] raw_advisor = new double[All_users.length];
double[] advisor_score = new double[All_users.length];
for (int i=0;i<All_users.length;i++){
for(int j=2;j<All_users[i].length;j++){
sum[i]+=All_users[i][j];
}
raw_advisor[i]=((sum[i]-(3*(All_users[i].length-2)))/4);
advisor_score[i]= 2.5+(2.5*(1-Math.pow(Math.E, -.5*raw_advisor[i])));
System.out.print("Customer ID "+All_users[i][0]);
System.out.print(", Domain "+All_users[i][1]);
System.out.println(": "+advisor_score[i]);
}
}
}
However I clearly over rely on the main method. I was wondering if anyone could help me integrate more methods and streamline the whole process. Thanks in advance, I am sorry again. I am new to Java and programming.
Although it may be small, it could be good practice taking a crack at making this more object oriented - here's a possible start.
The first thing suggested is from your comment
// These arrays represent individual users.
// The first value in the array is their customer number and the second is domain.
You don't say what the remaining numbers are, but from other comments I gather they are some kind of score. This suggests something like
public class CustomerDomain
{
private int customerNumber;
private int customerDomainID;
private List<Double> scores = new ArrayList<Double>();
public CustomerDomain(int number, int domainID)
{
this.customerNumber = number;
this.customerDomainID = domainID;
}
public void addScore(double score)
{
this.scores.add(score);
}
public List<Double> getScores()
{
return this.scores;
}
}
Although in real life I'd probably not have the scores embedded in the customer class.
This particular program, given it's small size, I would not refactor. Making an OO 'hello world' is trying to make a limousine out of a tricycle, IMO. In general, though, when I start a larger project I want to design with OO concepts in mind.
At a high level, I try to picture the 'entities' I will be building i.e. concrete 'employees,' abstract 'actions,' and their relationships. These real-world 'entities' typically become classes - which OO lends itself to modeling very well via inheritance and other related concepts. Their relationships are then described by the interfaces they expose - being careful to hide the 'internals' of each object to keep everything de-coupled.
Going more into detail, I identify the 'utility' code which multiple parts of my application might use - this may become a static/global helper class.
More detailed still, within a class, I try to restrict functions/methods to accomplishing one goal only, to reduce side effects.
Of course, I don't always get it right the first time. However, building larger and larger projects helps you recognize when certain design patterns work and when they will not. Time, budget, technologies, and so on, all play a part in this decision-making.
This is a really small amount of code, and if it works, why break it? That being said, read up a little on the Object Oriented paradigm, and then look at your problem the code is solving, and think about how it would work in that context. Good object oriented design generally tends to start out on paper, for me anyways.