To my knoweldge so far I thought that coupling relates to the degree in which two or more classes are "interconnected". In other words in which extent a class makes use of methods or variables of other classes. Our goal in a well designed Software System is of course to keep the coupling low (loose).
I am reading though currently a book, which states explicitly, that the objective of loose coupling is achieved by designing the System, so as every class to use only the API (public methods) of other classes and not directly their instance variables. Consequently the instance variables must be private. If that is the point, what is the difference between loose coupling and strong encapsulation? As far as I am concerned the later refers to encapsulation. What is actually true regarding the above notions of OO Software Development?
Loose coupling is more than just using a public API, it's also an ability to understand only that API, and not be dependent on specific implementations. It also includes limiting the amount of change required in dependent code across implementation differences.
Encapsulation isn't just about disallowing direct property access. It also includes making sure that internal data isn't exposed in a way that can cause unintentional behavioral (e.g., returning defensive copies of internal structures), and ensuring behavior, not just data, is properly isolated, and responsibilities are implemented in appropriate places.
Loose coupling is properly achieved by the judicious application of strong encapsulation. Weak encapsulation may provide loose coupling but may also introduce loopholes that allow for visibility of methods and variables outside of the abstraction's scope (inadvertant tight coupling). Strong encapsulation however, does not imply anything about coupling since a class of this nature can be designed to couple loosely, tightly, or not at all with external entities.
You may achieve loose coupling with strong encapsulation but encapsulation itself does not yet guarantee good code and loose coupling. Despite encapsulation you may still write tightly coupled code.
Loose coupling (a rule that no unnecessary dependencies between objects/modules are introduced) may be achieved without formal encapsulation (accessors/setters and restricted visibility).
But... If you write code for yourself or for a small set of skilled co-developers then referring directly to class members (thus breaking encapsulation) may facilitate keeping code smaller and easier to read and understand. C# has partially done it with properties - they look like plain class members but are in fact accessors and setters.
For bigger teams or reusable code I would say that strong encapsulation is a must. However you should always keep in mind flexibility - if you restrict your API too much it will become unusable. This is especially important if your code is not yet mature enough to handle all use cases with "official" API.
Related
I'm taking further intro java classes at the moment and this is how the class briefly defined this:
Cohesion: Aim for high cohesion, in this case cohesion meaning that a single module is tightly focused on its task.
Coupling: Aim for low coupling, in this case coupling meaning the level of extent in how intertwined two or more modules are.
How does one determine the level of cohesiveness as well as coupling?
For instance, some of my methods call other methods that are in the same class. This means that the method that calls other methods are dependent on the other methods in order for the "calling" method to finish its code block. Does this mean that I have low cohesion and high coupling on the methods of the same class? Or do these concepts refer more to different classes and different packages?
Cohesion and decoupling are important at all levels: each line of code should have a specific meaning and purpose, each method should have a specific meaning and purpose, each class should have a specific meaning and purpose, each package should have a specific meaning and purpose, each code repository should have a specific meaning and purpose.
This doesn't mean that a method shouldn't call another method, that a class shouldn't use another class, etc.; rather, it means that ideally, you should be able to read and understand a method without reading every other method it calls, to read and understand a class without reading every other class it uses, etc.
That said, we expect greater cohesion and decoupling for larger units: classes need to be much more cohesive and much less tightly coupled than methods do, for example, because assuming your classes are a reasonable size, you can much more easily go back and forth between methods than between classes when you're reading and maintaining the code.
There are metrics for cohesion / coupling; see https://softwareengineering.stackexchange.com/questions/151004/are-there-metrics-for-cohesion-and-coupling.
So the way to "determine" the level of cohesion / coupling is to implement a tool that measures the respective metrics. (Or find an existing tool that does this. For example, Sonar.)
How does one determine the threshold for the level of cohesion and/or coupling?
I assume you mean ... how do you decide when you will call values of the respective metrics "unacceptable" in your codebase.
Basically, that is up to you to decide. I would do it by looking at examples where the tool is reporting a "bad" value, and decide how bad I thought it really was. Alternatively, stick with the default thresholds in the tool that you are using.
I might be wrong, but here is just my humble input.
Cohesion is often time mentioned along with coupling, but they have an inverse relationship. High cohesion == low coupling.
Let me quote you
Aim for high cohesion, in this case cohesion meaning that a single
module is tightly focused on its task.
So it just means like that. Something that only does one thing and does it well. For example, a method to save an entity to the database should only focus on how to save that entity to the database, it should not worry about the correctness of that entity (Do all of that entity instance attributes pass all the database schema validations, in which case this validation should be handled maybe by an interceptor).
Coupling refers to the degree to which 2 modules depend on each other, the least the better because it promotes maintenance, and re-usability, etc. Often time, low coupling is achieved by using events, we have event emitters and event consumers, and they don't have to know anything about each other. Even emitters just fire-and-forget, and the consumers will take of the events when the system delivers the events to them.
I was going through an article about Object Oriented Programming and it stated that encapsulation means putting related items together, but I don't understand how the article's representative example: UserProfile.js. Though this example is in JavaScript, I'm looking to understand these concepts in Java.
Can anyone explain me these two questions with a pseudo code:
What is encapsulation?
Why do we need encapsulation with pseudo code?
Encapsulation isn't necessarily about putting related items together, it's a technique of hiding internal information of an object. I'm not sure if I agree with the premise of the author of the article you linked... I don't accept that a struct is really a method of encapsulation in the object-oriented sense of the word.
Encapsulation
Psudo [sic] code is a technique for explicitly writing coding logic without the need for syntactical constraints. Considering this context, I don't understand your second question.
Pseudocode
No, that is cohesion.
Encapsulation is hidding things from who doesn't need them.
Michael has it correct.
In Object Oriented programming Encapsulation is the first
pace. Encapsulation is the procedure of covering up of data and
functions into a single unit (called class). An encapsulated object is
often called an abstract data type.
ref: http://www.c-sharpcorner.com/UploadFile/ggaganesh/EncapsulationInCS11082005064310AM/EncapsulationInCS.aspx
Encapsulation is the hiding of the non-essential features.
So why do we need it.
Programing is about translating a solution to a problem into logical code to solve that problem. Because of this, there maybe many complicated methods and functions that we don't want Mr.Joe Blow developer to use. We will encapsulate (or BlackBox) those methods so they cannot be used (they are still used internally). This reduces complexity by only representing important functions and hiding others.
As for needing it in pseudo code, i'm not sure. Michael did a good job with explaining that.
I haven't had enough coffee to give a good example,Plus my Rubik's cube broke :(, i'll write one up for you.
The encapsulation stand for "hiding element for free usage", is a part of Object Oriented Programming paradigm.
It is used to specify the range of visibility elements of code.
Let assume that we have a class with field called password where the password is stored. If this password would be visible for everyone, then there would be no need for a password.
Additional thing is that this helps to maintain the code in order.
Encapsulation isn't goal in OODesign. It is only way to achieve the finest, needed abstraction.
What is encapsulation?
in specific - it means hiding properties from non-desirable access
in overall - it means hiding every project design decision which could be changed in future. Therefore in encapsulation we should consider also e.g. concrete method implementation. From this POV we encapsulate its behavior so that for some POV we don't want to know how it is doing it, knowing only what this method is doing. Encapsulation could be achieved also for example using inheritance mechanism!
How we use encapsulation/
Example - hide every class property. You could as why do we have to do so - it is much effort and unnecessary code! Consider simple example where you can set some int properties. In your scenario - this variable should be in specific range. If someone sets it wrong - how would you design workflow to prevent this action?
More sophisticated but still simple example are collections. In many cases we shouldn't provide full collections to your's object neighbourhood. Encapsulation allows you to provide every property client just a copy of your object. In some cases - it could be helpful.
I think to really understand and appreciate encapsulation you really need a little bit of history.
It used to be that if you wrote a program it would be kind of as though every line of code were printed on a single sheet of paper where everything has knowledge and access to everything else and there are no fancy constructs in which to hide or store variables out of site of your functions.
Lets say you are trying to write some program with 100 different functions and 100 variables. Can you imagine how disorganized and ugly that would get? Effectively, all that code is just a giant formless script that gets executed in some linear fashion and has no real structure, rhyme or reason to it other than that one line of code comes before another line of code and so on.
Encapsulation was invented to take a program like that and give it a skeletal structure, allowing you to hide and organize those 100 functions and variables into a sensible whole. In the case of your user info class here, they take everything that is relating to UserProfile and stick it in a "Capsule" so that it can only be accessed through a reference to to UserProfile. It might look like overkill in this context, but if you have a much larger program, you will be extremely happy to be able to do this.
Its a fancy word for something that is extremely obvious once you understand where the people who created these terms were coming from.
I think encapsulation is closely related to information hiding and abstraction. It is simply the practice of hiding implementation details and object internals from the outside world. It helps both with clarity as well as reducing coupling.
The capabilities of a class are declared in the interface of methods it defines, not in the detail of how they are implemented. Good encapsulation ensures the public interface is sufficient for callers to use without revealing internal implementation details. A well encapsulated design reduces coupling, as the internals can be replaced without affecting everything else that uses that class (through its interface).
Whilst there are many good examples on this forum that contain examples of coupling and cohesion, I am struggling to apply it to my code fully. I can identify parts in my code that may need changing. Would any Java experts be able to take a look at my code and explain to me what aspects are good and bad. I don't mind changing it myself at all. It's just that many people seem to disagree with each other and I'm finding it hard to actually understand what principles to follow...
First, I'd like to say that the primary reason you get such varying answers is that this really does become an art over time. Many of the opinions you get don't boil down to a hard fast rule or fact, more it comes down to general experience. After 10-20 years doing this, you start to remember what things you did that caused pain, and how you avoided doing them again. Many answers work for some problems, but it's the individual's experience that determines their opinion.
There is really only 1 really big thing I would change in your code. I would consider looking into what's called the Command Pattern. Information on this shouldn't be difficult to find either on the web or in the GoF book.
The primary idea is that each of your commands "add child", "add parent" become a separate class. The logic for a single command is enclosed in a single small class that is easy to test and modify. That class should then be "executed" to do the work from your main class. In this way, your main class only has to deal with command line parsing, and can lose most of it's knowledge of a FamilyTree. It just has to know what command line maps into which Command classes and kick them off.
That's my 2 cents.
I can recommend Alan's and James's book Design Patterns explained -- A new perspective on object-oriented design (ISBN-13: 978-0321247148):
It's a great book about has-a and is-a decissions, including cohesion and coupling in object-oriented design.
In short:
Cohesion in software engineering, as in real life, is how much the elements consisting a whole(in our case let's say a class) can be said that they actually belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.
One way of looking at cohesion in terms of OO is if the methods in the class are using any of the private attributes.
Now the discussion is bigger than this but High Cohesion (or the cohesion's best type - the functional cohesion) is when parts of a module are grouped because they all contribute to a single well-defined task of the module.
Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.
Loose coupling is a method of interconnecting the components in a system or network so that those components, depend on each other to the least extent practically possible…
In long:
I wrote a blog post about this. It discusses all this in much detail, with examples etc. It also explains the benefits of why you should follow these principles. I think it could help...
Coupling defines the degree to which each component depends on other components in the system. Given two components A and B ,how much code in B must change if A changes.
Cohesion defines the measure of how coherent or strongly related the various functions of a single software component are.It refers to what the class does.
Low cohesion would mean that the class does a great variety of actions and is not focused on what it should do. High cohesion would then mean that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Note: Good APIs exhibit loose coupling and high cohesion.
One particularly abhorrent form of tight coupling that should always be avoided is having two components that depend on each other directly or indirectly, that is, a dependency cycle or circular dependency.
Detailed info in below link
http://softwarematerial.blogspot.sg/2015/12/coupling-and-cohesion.html
If you had the chance to significantly change/update Java's classpath libraries, which things would you add/update/change/deprecate/remove?
Restructure all the various aspects of the currently far to monolithic class library into seperate modules with lower interdependencies. This would require to seperate interfaces and provided default implementations into distinctive class hierachies (similar to what exists for the SAX API already). Rationale: allow deployments with stripped down class libraries and additionally enable third party replacementes and extensions of certain central aspects (crypto, network protocols, i18n, ...).
Redesign all collection classes and some of the java.lang classes into much smaller building blocks that can be assembled into more flexible and more powerfull data structures (along the philosophy of the Google Collections classes). This would offer far more context independant behavioural interfaces, like i.e. CharSequence or Comparable.
Provide more platform specific (Extension-)APIs and implementations that cover as much as is reasonable of the supported platforms (and grow with them) and accept that code that is using these classes will not be portable without extra effort from the developer. This is meant to allow the creation of non trivial software that is able to compete with native software in terms of usability, usefullness and general perceived quality. These APIs would for example allow access to block devices, vt100 terminals, the Windows registry etc.
Redesign Swing in a multilayered way (i.e. controls on top of basic building blocks on top of a graphics primitives API) and make it far more polymorphic. I.e a single Action interface with a single method perform instead of lots of special Listener interfaces. Additionally I'd offer a wrapper framework that encapsulates native GUI components (in the spirit of my previous proposal).
Try to find a better way to handle security related access restrictions for sandbox environments that doesn't limit the overall flexibilty of many imporatant fundamental classes. Currently language features originaly intended for design purposes are heavily abused for security purposes which has led to rather static and nonpolymorphic classes and APIs because they could be expoited from within a sandbox if they were more open (and the approach still failed to be secure enough many many times).
Provide a less naive serialization system that supports weak references, has error detection and supports class evolution.
I'd add CheckedException at the same level as RuntimeException (make it less often that people "have" to catch Exception)
I'd remove all the deprecated APIs.
I'd remove the old collection classes, like Vector and Dictionary.
I'd make a boat load of exception classes under IOException.
I'd replace as many public static final int X; constants as I could with enums.
I'd get rid of Object.hashCode and define a Hashable / Hasher interfaces instead. (But I'd retain System.identityHashCode(Object) because despite its overheads it does something very useful that is impossible to do any other way.)
I'd get rid of Object.equals and define an Equatable / Equater interfaces instead. (But with better names if I could manage it.)
I'd get rid of Object.clone. I might retain it as a method on the array classes.
I'd get rid of Object.finalize and replace it with something that naive C/C++ programmers won't notice until they are experienced enough to know that finalization is almost always the wrong solution.
I'd get rid of System.gc();
I'd replace the clunky global System.in/out/err stuff with something that used Readers/PrintWriters and that was / could easily be "scoped" by thread or threadgroup.
I'd remove the ability to take a primitive lock on any Object (... OK not strictly library change).
I'd try figure out how to implement safe versions of thread.stop/suspend/resume ... even if this meant implementing Isolates in J2SE JVMs.
I have a question about Java style. I've been programming Java for years, but primarily for my own purposes, where I didn't have to worry much about style, but I've just not got a job where I have to use it professionally. I'm asking because I'm about to have people really go over my code for the first time and I want to look like I know what I'm doing. Heh.
I'm developing a library that other people will make use of at my work. The way that other code will use my library is essentially to instantiate the main class and maybe call a method or two in that. They won't have to make use of any of my data structures, or any of the classes I use in the background to get things done. I will probably be the primary person who maintains this library, but other people are going to probably look at the code every once in a while.
So when I wrote this library, I just used the default no modifier access level for most of my fields, and even went so far as to have other classes occasionally read and possibly write from/to those fields directly. Since this is within my package this seemed like an OK way to do things, given that those fields aren't going to be visible from outside of the package, and it seemed to be unnecessary to make things private and provide getters and setters. No one but me is going to be writing code inside my package, this is closed source, etc.
My question is: is this going to look like bad style to other Java programmers? Should I provide getters and setters even when I know exactly what will be getting and setting my fields and I'm not worried about someone else writing something that will break my code?
Even within your closed-source package, encapsulation is a good idea.
Imagine that a bunch of classes within your package are accessing a particular property, and you realize that you need to, say, cache that property, or log all access to it, or switch from an actual stored value to a value you generate on-the-fly. You'd have to change a lot of classes that really shouldn't have to change. You're exposing the internal workings of a class to other classes that shouldn't need to know about those inner workings.
I would adhere to a common style (and in this case provide setters/getters). Why ?
it's good practise for when you work with other people or provide libraries for 3rd parties
a lot of Java frameworks assume getter/setter conventions and are tooled to look for these/expose them/interrogate them. If you don't do this, then your Java objects are closed off from these frameworks and libraries.
if you use setters/getters, you can easily refactor what's behind them. Just using the fields directly limits your ability to do this.
It's really tempting to adopt a 'just for me' approach, but a lot of conventions are there since stuff leverages off them, and/or are good practise for a reason. I would try and follow these as much as possible.
I don't think a good language should have ANY level of access except private--I'm not sure I see the benefit.
On the other hand, also be careful about getters and setters at all--they have a lot of pitfalls:
They tend to encourage bad OO design (You generally want to ask your object to do something for you, not act on it's attributes)
This bad OO design causes code related to your object to be spread around different objects and often leads to duplication.
setters make your object mutable (something that is always nice to avoid if you can)
setters and getters expose your internal structures (if you have a getter for an int, it's difficult to later change that to a double--you have to touch every place it was accessed and make sure it can handle a double without overflowing/causing an error, if you had just asked your object to manipulate the value in the first place, the only changes would be internal to your object.
Most Java developers will prefer to see getters and setters.
No one may be developing code in your package, but others are consuming it. By exposing an explicitly public interface, you can guarantee that external consumers use your interface as you expect.
If you expose a class' internal implementation publicly:
It isn't possible to prevent consumers from using the class inappropriately
There is lost control over entry/exit points; any public field may be mutated at any time
Increase coupling between the internal implementation and the external consumers
Maintaining getters and setters may take a little more time, but offers a lot more safety plus:
You can refactor your code any time, as drastically as you want, so long as you don't break your public API (getters, setters, and public methods)
Unit testing well-encapsulated classes is easier - you test the public interface and that's it (just your inputs/outputs to the "black box")
Inheritance, composition, and interface designs are all going to make more sense and be easier to design with decoupled classes
Decide you need to add some validation to a mutator before it's set? One good place is within a setter.
It's up to you to decide if the benefits are worth the added time.
I wouldn't care much about the style per se (or any kind of dogma for that matter), but rather the convenience in maintainability that comes with a set of getter/setter methods. If you (or someone else) later needed to change the behavior associated with a change of one of those attributes (log the changes, make it thread-safe, sanitize input, etc.), but have already directly modified them in lots of other places in your code, you will have wished you used getter and setter methods instead.
I would be very loath to go into a code review with anything but private fields, with the possible exception of a protected field for the benefit of a subclass. It won't make you look good.
Sure, I think from the vantage point of a Java expert, you can justify the deviation from style, but since this is your first professional job using Java, you aren't really in that position.
So to answer your question directly: "Is this going to look like bad style?" Yes, it will.
Was your decision reasonable? Only if you are really confident that this code won't go anywhere. In a typical shop, there may be chances to reuse code, factor things out into utility classes, etc. This code won't be a candidate without significant changes. Some of those changes can be automated with IDEs, and are basically low risk, but if your library is at the point where it is stable, tested and used in production, encapsulating that later will be regarded as a bigger risk than was needed.
Since you're the only one writing code in your closed-source package/library, I don't think you should worry too much about style - just do what works best for you.
However, for me, I try to avoid directly accessing fields because it can make the code more difficult to maintain and read - even if I'm the sole maintainer.
Style is a matter of convention. There is no right answer as long as it is consistent.
I'm not a fan of camel, but in the Java world, camelStyle rules supreme and all member variables should be private.
getData();
setData(int i);
Follow the Official Java code convention by Sun (cough Oracle) and you should be fine.
http://java.sun.com/docs/codeconv/
To be brief, you said "I'm asking because I'm about to have people really go over my code for the first time and I want to look like I know what I'm doing". So, change your code, because it does make it look like you do not know what you are doing.
The fact that you have raised it shows that you are aware that it will probably look bad (this is a good thing), and it does. As has been mentioned, you are breaking fundamentals of OO design for expediency. This simply results in fragile, and typically unmaintainable code.
Even though it's painful, coding up properties with getters and setters is a big win if you're ever going to use your objects in a context like JSP (the Expression Language in particular), OGNL, or another template language. If your objects follow the good old Bean conventions, then a whole lot of things will "just work" later on.
I find getters and setters are better way to program and its not about only a matter of coding convention. No one knows the future, so we can write a simple string phonenumber today but tomorrow we might have to put "-" between the area code and the number, in that case, if we have a getPhonenumber() method defined, we can do such beautifications very easily.
So I would imagine, we always should follow this style of coding for better extensibility.
Breaking encapsulation is a bad idea. All fields should be private. Otherwise the class can not itself ensure that its own invariants are kept, because some other class may accidentally modify the fields in a wrong way.
Having getters and setters for all fields is also a bad idea. A field with getter and setter is almost the same as a public field - it exposes the implementation details of the class and increases coupling. Code using those getters and setters easily violates OO principles and the code becomes procedural.
The code should be written so that it follows Tell Don't Ask. You can practice it for example by doing an Object Calisthenics exercise.
Sometimes I use public final properties w/o get/setter for short-living objects which just carry some data (and will never do anything else by design).
Once on that, I'd really love if Java had implied getters and setters created using a property keyword...
Using encapsulation is a good idea even for closed source as JacobM already pointed out. But if your code is acting as library for other application, you can not stop the other application from accessing the classes that are defined for internal use. In other words, you can not(?) enforce restriction that a public class X can be used only by classes in my application.
This is where I like Eclipse plugin architecture where you can say what packages in my plugin can dependent plugins access during runtime. JSR 277 aimed at bringing this kind of modular features to JDK but it is dead now. Read more about it here,
http://neilbartlett.name/blog/2008/12/08/hope-fear-and-project-jigsaw/
Now the only option seems to be OSGi.
While I am well aware about the common pressure to use getters and setters everywhere regardless the case, and the code review process leaves me no choice, I am still not convinced in the universal usefulness of this idea.
The reason, for the data carrying classes, over ten years of development it has never been for me a single case where I would write anything different from set the variable in the setter and read the variable in the getter while lots of time has been spent on generating, understanding and maintaining this cargo cult code that seems not making any sense.
The data class is a structure or record, not a class. It does not do anything itself. Other classes are making changes to it. It should not be any functionality there at all, leave alone the functionality in the setters or getters. Java probably needs a separate keyword for the multi-field data record that has no methods.
From the other side, the process seems gone so far now that probably makes a lot of sense to put getters and setters just from beginning, even first time in the new team. It is important not to conflict with the team.