Cohesion can be defined as the degree to which the elements of a module belong together.
Visualizing it helps. Imagine the attributes of a class and the methods. If your class is cohesive, it means the methods are going to use many of the attributes, and conversely, the attributes will be used by many of the methods. This is the "sticking together" notion of cohesion. I like the following visualization that comes from NDepend's placemat:
As others pointed out, the methods that direct the plane (e.g., directToX
) are possibly outside of the "theme" of what is a Plane, but they're not flagrantly wrong. Those elements (responsibilities) might be better in another class, say, AirTrafficController
. In reality, planes don't decide much how they fly. Their pilots must follow instructions from the ground.
I'd argue that the Thread stuff (start
, run
) is definitely outside the theme of a Plane. Those methods hardly use anything that are part of a Plane
(they are distractions from its theme). You could use an anonymous inner class to handle the processing in a thread from the main
and your Plane would be even more reusable (and cohesive).
A cohesive object gets to the essence of the thing it models. This means it could more likely be re-used easily in another application (or even another OO language). Anything that starts to creep outside the true theme of your concept will likely make it harder to re-use the concept in another application. The "distractions" don't make sense anymore in another application.
If you're developing a Kamikaze project (one where you just want to make it work and don't care about re-use), it's perfectly OK to forget about cohesion (and other design elements). Design choices are trade-offs. You could refactor your Plane class to make it more cohesive, but if you never reuse it in another application, you've perhaps wasted your time. On the other hand, design is a learning process; even if you over-design something for one application, you maybe learned something for the next.
Finally, all design aspects are difficult to quantify and therefore there are few standards. Some companies have been known to set (arbitrary) standards for metrics such as LCOM in their development processes. I've read of team standards that say if a class has bad value for LCOM, then it must be refactored until its value goes low enough (its cohesion is stronger). Unfortunately, LCOM can be a bad measure of cohesion (especially in classes that have lots of get/set methods).