Skip to main content

Review - The Object-Oriented Thought Process, by Matt Weisfeld


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


Comments

  1. Rất dễ hiểu, thanks a đã chia sẻ. mà a có thể giải thích rõ phần From Procedural to Object Oriented. Đoạn này có nghĩa là gì vậy? "a handshaking agreement must be defined for the client and server in order to work together"

    ReplyDelete
    Replies
    1. Ví dụ dẫn trong phần này tôi "chôm" nguyên của tác giả á. :D
      Theo cách hiểu đơn giản, thực chất ví dụ này không mang tính so sánh mà chỉ đưa ra hai hướng tiếp cận khác nhau của Procedural và OO. Ở ví dụ này, chúng ta thấy thay vì hướng tiếp cận của OO là truyền nguyên một đối tượng về cho client thì cách tiếp cận của Procedural là chỉ truyền dữ liệu (JSON) về serve và cả 2 phía server và client đều phải biết rõ format của JSON và tác giả gọi cái đó là "handshaking agreement" - nghe có vẻ hơi hàn lâm, làm như kiểu làm việc của giao thức (protocol) nhưng thấy cũng hợp lý nên tôi giữ nguyên ý đó luôn.

      Delete
  2. ok a, mà e thấy trong hướng tiếp cận OO thì cả server lẫn client cũng vẫn phải cùng define format của json chứ nhỉ

    ReplyDelete
    Replies
    1. OO quan niệm mọi thứ là object và các objects giao tiếp với nhau. Do đó, ví dụ về truyền dữ liệu giữa server và client bằng JSON không phải là hướng tiếp cận của OO. Ở đây, chúng ta không bàn về công nghệ mà bàn về cách tiếp cận. Với JSON, cho dù lập trình theo hướng nào đi nữa thì cũng như nhau.

      Delete
    2. thanks a, mà vẫn chưa clear lắm, ráng đọc thêm vậy -.-

      Delete
  3. Procedural Programming là phong cách program theo hướng thủ tục như Pascal ngày trước.
    Một chương trình là tập hợp 1 tuần tự thực thi của các thủ tục (Procedure) khác nhau. Để chia sẽ data giữa các thủ tục này, người ta có thể định nghĩa data ở global (toàn bộ các thủ tục đều access được) hoặc clone data và giữ ở từng thủ tục riêng lẻ. Mỗi thủ tục (procedure) sẽ phụ trách 1 tác vụ khác nhau và tương tác với nhiều loại data khác nhau.
    Điều này đem đến sự mất kiểm soát data và các procedure phải có sự thống nhất về format để chúng có thể hiểu data như nhau.
    Mặc khác, OOP nhìn sự thực thi của 1 ứng dụng như là sự tương tác giữa các Objects với nhau.
    Mỗi object có 1 bộ behaviour ,data và context riêng biệt. Người ta có thể sử dụng object bằng cách gọi behaviours của nó mà không cần quan tâm đến data format hay thứ tự thực thi lệnh bên trong implementation của nó.
    Ví dụ:
    POP : để bắt đầu chạy xe (thứ tự tuần tự)
    - CheckIfCarIsFueled()
    - InsertKey()
    - StartEngine()
    - Gear()
    - Speedup()
    OOP: để bắt đầu chạy xe
    - car.start()
    (behaviour start của car giả định đã implement các bước cần thiết).

    ReplyDelete
  4. Good job men, since the last time I asked you " Do you have a blog ?" Seems your blog come so far, and mine is still stand at the time.

    ReplyDelete
    Replies
    1. Thanks. There are still very few posts. ;)
      Oops! It looks like you've already moved your blog into a new domain? I could not reach the "dumbass-developer" anymore.

      Delete

Post a Comment

Popular posts from this blog

My 2017 Review

Passion for System Design After finishing a one year project, my longest stable team (3 years) was separated into two smaller teams. Sadly, but that was a good chance for me to become a key member in my new team. My preferred skills is about system architectures; therefore most of the tasks of building the application structures are handled by me. In order to enhance my design system skills, I have spent much my time for reading books closely after work. These following books helps me a lot.
- Object-Oriented Thought Process | Matt Weisfeld
- Head First Design Pattern | Elisabeth Freeman and Kathy Sierra
- Java 8 in Action: Lambdas, Streams, and Functional-style Programming | Alan Mycroft and Mario Fusco
Junior Technical Architect I was requested to join a technical architect team (aka Team. Alpha) where I actually has gained experiences almost on interviewing candidates for my company (lol). Besides, I noticed myself must improve the skills of convincing people because I have had a …

AngularJS - Build a custom validation directive for using multiple emails in textarea

AngularJS already supports the built-in validation with text input with type email. Something simple likes the following:
<input name="input" ng-model="email.text" required="" type="email" /> <span class="error" ng-show="myForm.input.$error.email"> Not valid email!</span>
However, I used a text area and I wanted to enter some email addresses that's saparated by a comma (,). I had a short research and it looked like AngualarJS has not supported this functionality so far. Therefore, I needed to build a custom directive that I could add my own validation functions. My validation was done only on client side, so I used the $validators object.

Note that, there is the $asyncValidators object which handles asynchronous validation, such as making an $http request to the backend.

This is just my implementation on my project. In order to understand that, I supposed you already had experiences with Angular…

Strategy Design Pattern

For example, I have an program with an Animal abstract class and two sub-classes Dog and Bird. I want to add a new behavior for the class Animal, this is "fly".  Now, I face to two approaches to solve this issue:

1. Adding an abstract method "fly" into the class Animal. Then, I force the sub-classes should be implemented this method, something like:

public abstract class Animal{ //bla bla public abstract void fly(); } public class Bird extends Animal{ //bla bla public void fly(){ System.out.println("Fly high"); } } public class Dog extends Animal{ //bla bla public void fly(){ System.out.println("Cant fly"); } }
2. Creating an interfaces with method "fly" inside. The same issue to abstract class, I force the classes these implement this interface should have a method "fly" inside:

public interface Flyable{ public void fly(); } public class Bird implements Flyable{ //bla bla public void fly(){ System.out.println…

How did I start practising BDD?

At the beginning days I have practised TDD (Test Driven Development) with using JUnit, I approached that I should test methods belong to a class. For example:

I have a class with some methods:

public class A{ public void method1(){ } public void method2(){ } }
And then, I wrote some test methods to check the corresponding ones, for example:

public class ATest{ @Test public void testMethod1(){ .... assertTrue(...); ..... assertEquals(...); } @Test public void testMethod2(){ } }
After that, I know that a test method (ex: testMethod1) should just only tests one thing, so I decided to write more methods for each cases. It looks like the following:

@Test public void testMethod1_When_Case1(){ .... assertTrue(...); } @Test public void testMethod1_When_Case2(){ .... assertEquals(...); }
However, it was not a really good approach because it seems that I just focused on test the functionality of the method of the class. With TDD approach, I knew that I should test the…

Styling Sort Icons Using Font Awesome for Primefaces' Data Table

So far, Primefaces has used image sprites for displaying the sort icons. This leads a problem if we want to make a different style for these icons; for example, I would make the icon "arrow up" more blurry at the first time table loading because I want to highlight the icon "arrow down". I found a way that I can replace these icons to Font Awesome icons.


We will use "CSS Pseudo-classes" to archive it. The hardest thing here is that we should handle displaying icons in different cases. There is a case both "arrow up" and "arrow down" showing and other case is only one of these icons is shown.

.ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s { background-image: none; margin-left: 5px; font-size: 1.1666em; position: relative; } .ui-sortable-column-icon.ui-icon.ui-icon-carat-2-n-s:not(.ui-icon-triangle-1-s)::before { content: "\f106"; font-family: "FontAwesome"; position: absolute; t…