14 May 2014

Encapsulation misunderstanding

During a discussion with Dr. Andrea Mocci about object oriented design, he told me that it's wrong to implement accessors that directly assign collection to the variable or return the collection itself.
public ArrayList<string> getList() {
    return list; 
}

public void setList(ArrayList<string> list) {
    this.list = list
}
Because in this case anyone can change the internal state of your object. The suggestion was to replace setter with addItem(String item) and removeItem(String item) that will add an item to the list or remove it respectively. As for getter the suggestion was to use immutable wrapper, so that client won't be able to modify it. And here is the interesting part. Pharo, the language that I use now 99% of all time, does not have immutable collections. This is one more case where it seams that Pharo is missing leavers to enforce a good quality of design, but on the other hand I've never seen anywhere as well written software as in Pharo. Despite the complex semantics, static typing and other shamanism C++ and Java didn't manage to enforce good design of the projects.  Out of curiosity I've started a discussion on pharo-dev mailing list and the replies were very interesting.

Firs of all Pharo provides even better approach for "getting" a collection. If you are not familiar, there are higher order functions that are heavily used. So if you want to execute someMethod for all elements of aCollection, all you have to do is:
aCollection do: [ :element | element someMethod ]
or in a shorter way: aCollection do: #someMethod. Now nothing forbids you to implement forListDo: method in your class which will execute desired actions for each item of encapsulated list. How cool is that?

Another important question is: "Does encapsulation mean that you have to do everything to forbid client form accessing your internal state directly?" If the answer is "yes" then it's ok to say, that you cannot encapsulate data in Pharo. As it's a completely reflective environment, where you can do things like:
(someObject instVarNamed: 'internalCollection') add: junk
In the example above we get an instance variable called internalCollection from object someObject and add variable called junk to it. Do developers use this a lot? Not at all. But you have this functionality because it's crucible for some specific tasks. Also there is a StackOverflow answer describing how to access private field in java.

Also as Igor Stasenko pointed out:
Should encapsulation protect also from modifying the items themselves? Or any object(s) accessible through items? Or any objects accessible through all objects accessible through items?

This issue brings me to the same compulsion that I had previously. Languages like Java make you think how to punch a client in face if he does something that you don't want him to do. Thus all development is focused on avoiding punches from other developers and preparing a new ones for people that will use your code. Pharo is dead-simple in it's syntax and principles. This way during development you focus on providing the convenient api so the clients do not have to rely on internal state of your objects while performing the tasks they need.

Stay awesome!
P.S. I'm not trying to say that if you are programming in C++ or Java, you are writing a bad code. You can write really good code in your language as well as writing bad code in Pharo or other Smalltalk dialects. But in general code quality depends on a language anyway. For example it is really easy to do something wrong in JavaScript. My key idea is that Java has so many complications to enforce good coding support, that instead of thinking how to write a good code developers are actually overcoming Java obstacles.

1 comment:

  1. Borgata Hotel Casino & Spa - Biloxi - JetBlue
    Borgata Hotel Casino 전주 출장안마 & Spa, Biloxi (NJ) · Other Locations · Casino 대구광역 출장안마 · Events Center. 동해 출장샵 Borgata Hotel 안산 출장마사지 Casino 파주 출장안마 & Spa.

    ReplyDelete