Obviously you designed your classes the way to learned during the Object Oriented Lessons, and you make sure that all variables are private, and your setters only accept the correct values.
But, now that you are make more complex class structures you should be aware of how things interact.
Lets assume you built a class that allows you to store data in an ordered fashion. Every time you add a new element to your own list, it is placed at the correct location though your very clever algorithm. The data we store has for instance a numeric priority. (The other information doesn’t really matter.)
[ (3), (7), (12) ]
[ (3), (7), (9), (12) ]
Now for the problem… Let’s assume that the class provides public methods that channge the priority of the object.
In this example we’re going to change the “internal state” of element 2 to a state that should have been ordered differently.
[ (3), (7), (5), (13) ]
Question: Does your ordered list remain ordered after the data is changed?
Answer: Nope!
classDiagram
class ListOwner {
-myList : List~String~
+getList() List~String~
}
class List {
+addItem() void
+replaceItem() void
+removeItem() void
}
class OtherClass {
+changeTheList() void
}
ListOwner --> List
List <-- OtherClass
In the situation described above there is no way to keep the list ordered. We need to trust that the people that we give access to the list won’t mess things up.
The ListOwner
class maintains a reference to its list and knows how to add and remove elements of the list.
Because it is designed to keep the list ordered, all internal implementations make sure of that. But an external party (OtherClass
) doesn’t have this knowledge (or responsibility).
They only know that they are presented with a reference to a List
class that allows it’s elements to be changed, and they will happily do so. Even when they know that the list should
remain ordered, there is no way to guarantee that they cannot make illegal changes.
If your List
reference implements a public interface that may change the order of its elements, then you should not only keep that list private, but you should also prevent external parties from changing the various elements in your list.
To avoid any problems, simply keep everything to yourself. External parties don’t know your list or its internal data.
classDiagram
class ListOwner {
-myList : List~String~
-getList() List~String~
}
Disadvantage: External parties cannot access the content of the list.
If external parties need to have access to the list, and you don’t want your data elements to be altered, then you can provide those that are interested with a copy of your list, that contains copies of each element.
If the external party changes their version of the data, then your original data remains unaltered.
classDiagram
class ListOwner {
-myList : List~String~
-getCopyOfList() List~String~
}
ListOwner --> MyList
MyList .. YourList : copy of
YourList <-- OtherClass
Disadvantage: If external parties make changes, you will never know.
In order to manage the way elements are changed, you could, if you really wanted, create your own set of methods to provide to external parties. This way users need to tell you what they want to change, and your class can then protect the integrity of the list. You can, for instance, first remove the edited element, then change it, and place it back.
classDiagram
class ListOwner {
-myList : List~String~
-getList() List~String~
+addItem() void
+replaceItem() void
+removeItem() void
+getItemAt(index : int)
+???()
}
class OtherClass {
+changeTheList() void
}
ListOwner <-- OtherClass
Disadvantage: You need to define the entire “make changes” interface. Twice.
If you want your users to be allowed to make all possible changes to your data, and you don’t like any of the above solutions, then there is nothing for it, you need to clean up afterward.
Right before the ListOwner
needs to use the data again, you must removed unwanted data (such as null values) yourself, and then reorder your list.
External access to your internal data structure by reference may be very dangerous. Even when you have handled encapsulation perfectly, you must remain aware of the way your designs work together.