In this post, I would like to point out what I understood after closing my eyes and thinking about what exactly I have learned from this book. That means the layout of content does not follow the book.
From Procedural to Object Oriented
Once upon a time, there is an issue that it is very hard to test and debug in Procedural programming because the data is sometimes global and can be modified by multiple functions.Object-Oriented (OO) programming addresses these problems by combining both data and functions into an object. That means only functions belong to the object can access its own data.
Let us check the below two different approaches for a case that we want to transfer information between clients and servers across a network.
- Procedural programming: a client (browser) transfers a JSON data to a server which needs to know how to process with this data. In order words, a handshaking agreement must be defined for the client and server in order to work together.
- OO programming: a server transfers a Java object/applet to a client and the browser has no idea of what object will do. When the object is loaded the browser just executes the function and uses the data contained within the object.
Data hiding
Now, it is time for us to talk about OO more. The following mindset should be kept when designing the OO system.A change to the implementation should not require a change to the interfaces. For example, the provider changes the equipment, they don't change the way we make a call when using a cell phone.
It is much more useful/reusable to have an abstract interface such as "drive me to the airport" than to have separated concrete interfaces such as "turn right", "turn left", "start", "stop" and so on. For example, the interface "take me to the airport" is generally the way to go for a good, reusable OO design whole implementation would be different in Chicago, New York or Cleveland.
When designing a class, the rule of thumb is to always provide the users with as little knowledge of the inner workings of the class as possible. That means:
- The class has as few interfaces as possible.
- Public interfaces define what users can access.
- Design classes from a user's perspective and not from an information systems viewpoint.
- Go over the requirements and design with the people who will actually use it.
Do you see that all of these points above are related to the term “data hiding”?
Message
So far, we have talked about the way of OO “combining both data and functions into an object” with some basic mindsets that is called “encapsulation” concept. Now, we discuss about one more important concept is “polymorphism” and the term “message” in OO.Polymorphism literally means many shapes. When a message is sent to an object, the object must have a method defined to respond to that message.
For example, we have three Shapes: Circle, Square and Star. Even though we treat them all as the same Shape objects, and send a “Draw” message to each Shape object, the end result is different for each because Circle, Square and Star provide the actual implementation.
In Java, we have some mechanisms to implement this concept:
- Overriding: by Abstract class or Interface
- Overloading: same method names in a class
These ways are right for both constructors and member methods.
Code reuse
The term “code reuse” is important for any programming paradigm, not only in OO.In OO, both inheritance and composition are mechanisms for implementing this concept. However, the choice of using inheritance and composition should be considered. Let’s see how different they are.
Inheritance
Inheritance represents the “is-a” relationship. For example, a dog is a mammal. There is a true parent/child relationship.Pros:
- The reused code is in a single place (super class) so it not only saves some coding time but saves testing and maintenance time .
Cons:
- The change from the super-classes ripples through the class hierarchy. The testing would become more difficult, if not untenable.
To reduce the risk posed by dilemma, it is important that we stick to the strict “is-a” condition when using inheritance. For example, the window is really not a true rectangle.
Composition
Composition represents a “has-a” relationship. For example, a car has an engine. There is no parent/child relationship in this case.Pros:
- Overcome the issue of Inheritance, without forcing the sub-classes when super-class changes
Cons:
- Using too much composition can also lead more complexity, it is difficult to understand and maintain.
The fact that composition might be more appropriate in most cases does not mean that inheritance is evil. Therefore, the bottom line is developers simply need to take the time to understand the strengths and weaknesses of both and to use each in the proper contexts.
Contract
The “contract” concept here is any mechanism that requires a developer to comply with the specifications of an application-programming interface (API). Without enforcement, a rogue developer could decide to reinvent the wheel and write her own code rather than use the specification provided by the framework.In Java, the simple rule for defining a contract is to provide an unimplemented method, via either an abstract class or an interface.
OO in Nutshell
So far, I have not only categorized things by some basic terms in OO (data hiding, message, code reuse and contract) but also talked about the fundamental concepts of OO includes encapsulation, inheritance, polymorphism and composition inside each term.References
[1]. Matt Weisfeld, The Object-Oriented Thought Process, 3rd Edition.
[2]. https://daynhauhoc.com/t/tinh-da-hinh-trong-java-polymorphism-in-java/32369/8