Basics

This is the first chapter from the book.

Terminologies are abundant in the realm of design patterns. Without the terms being defined the interpretations vary which often lead to confusion. In this chapter, we try to define the various terms that we use so that there is less ambiguity in the concepts.

So what are the basic tools you have?
Forget Eclipse, I'm talking of the essential constructs using which you always write code; and you can consider them also as the various tools using which you design your code, important ones among these are
1.     Method or a function
2.     Object
3.     Class
4.     Interface
5.     Understanding the term implements
6.     External system
7.     Defining an object to use
8.     External view of objects
9.     Concept of terms such as implements/behavior
10.  State of an object
The aim of this chapter is to revisit these basic constructs and use them as tools to implement the design.
What is the method or a function?
A piece of reusable code! Who said you did not write reusable code? Every method is reusable; to what extent and if it ever has been reused is the question. When we write a method we often think of what will go inside the method; at least that is where it mattered most for grades. It is indeed the logic within the method and if you are thinking of theta and bigoh (complexity measures) then logic within the method is the place where you focus most. Our focus is different; apart from the complexity, we are thinking on modularity, reusability, scalability etc. What we are more interested in (you should be also) is the access level of the method that is who can access it; what are the arguments it takes; what it returns? Do I want to make an addition method so generic that it can add both strings and two numbers? Further, when we write a method, we need to understand whether the method can be called or needs to be called without instantiating the class. Should the method belong to the class? Or should it belong to the objects? So when we write a method we must not only think of what goes inside the method but also on what are the access level of the method, inputs and outputs of the method etc..

Six fundamental considerations towards defining a method - In the treatment for Singleton pattern, we identify six important questions that the reader can ask to design a method that is most appropriate for the problem at hand. These are
1.     What should be the output of the method?
2.     What would be the access level of the method?
3.     What should be the inputs of the method?
4.     What should be the logic within the method?
5.     Who will be calling it?
6.     Is the place being considered to define the method, the right place for defining the method?
We shall demonstrate the usage of these questions in the Singleton pattern. For subsequent patterns, we ask only those questions which are relevant. 

What is an object?
An object is a way to encapsulate data/variables and methods so that we can consider them in isolation. We in general look for this data to be not available outside this object and to be only available to methods inside the object. That is the ideal scenario; however, sometimes we need data to be set from an external piece of code. Now this can happen only two times, either during its creation or during the lifetime of the object. If it is during creation, then they should be passed as arguments in the constructor. If the data requires being set during the life cycle of the object then we must use setters for that particular variable. It is the not particularly nice to use the Eclipse feature of generating all getters and setters indiscriminately. Similar to the setting of a variable, getters should only be used for a variable if the object requests to part with their piece of data to the external world. The other thing that objects contain is the methods about which we have just discussed.

What is a class?
Now there can be many objects, each behaving differently, some of them may be the same or behave similarly, how do we then give a name to the feature? We do this by saying some object belong to a particular type while others are of a different type. A synonym for type is class. This concept was so common that language designers went ahead and made this a language construct or feature itself called Class. So if you have to create objects of a certain type, you defined first the type. To convey to the machine that it is a type you are defining you use the term, Class. Later using this feature you can define many objects and it all those object would be said to be objects of that Class. Thus, the class is defined as a template for creating objects.

What is an interface?
It is a set of methods.

What are the different ways in which you can interact with an object? You can call new upon the constructor, use the dot notation to access one of its variables (if accessible) or you can call one of its methods. Interface is a name to denote a set of methods with which you can interact with a class (or one of its objects) excluding the constructor. We can say that an object interfaces (interacts) with the external world via this interface. Thus, every class (or one of its objects) has an interface. We often need to define this set (read interface) of methods in advance. This is sometimes helpful and that itself is a fundamental pattern, and thus again included in the language construct itself by the designers, so that we can define just the interactions, without even thinking of classes which will provide (read implement) these methods.

What do implements mean?
The classes created later which are required to provide this set of methods thus use the word “implements” i.e. public ClassA implements InterfaceI.

Can an object have multiple interfaces?
Yes, it can. Let us say an object has methods m1, m2, m3 apart from the constructor of the object. So there can be six total possible permutations of these methods and thus six total interfaces possible. Now in the design, we may define only a few of these as required.

Do interface/implements and behavior refer to the same thing?
This is often a source of confusion. All such classes which implement a particular interface can be expected to behave in the same way, that is one can call the same method (of the implemented interface) over each of this classes. Thus, the term behavior is also sometimes used to describe an interface. But this is incorrect. Interface and behavior are not the same.  Interface refers to the set of methods and their signature while behavior refers to logic within the method. So two classes implementing the same interface will have same methods but can have different behavior of the methods depending upon the logic that is implemented within the methods.

What do we mean by same behavior?
Objects of a class would have the same logic within its methods, so they are in general referred to as having the same behavior (usually). Again two classes implementing the same interface will, at least, have same methods but can have different behavior of the methods depending upon the logic that is implemented within the methods. Note that a different class implementing the same interface does not automatically mean different behavior.
What is an external system?
An external system is any piece of code(s), systems, actors which interact or call or invoke the code that we are designing. This is not so much of a tool but helps in thinking; that is to consider everything within the class(es), objects and interfaces being considered as internal; outside it as external. The external system can vary to a very great degree, if the classification factor used is form, for example, it can be just another class or the code using which I am testing the class in question. The class again could be in the same package or different package. It could be within our systems or residing within a system situated miles apart! We do not need to make a distinction beyond this, it suffices to consider the external system as any users of the class (or framework or pattern) in question and leave rest upon the context.

The fundamental design patterns
We earlier noted that terms class, interface, implements are very basic, so much so that it is incorporated as keywords within the language, but more deeply, do you see that these are also design patterns? It is possible that you may not have realized this before and it is the core essence of design patterns.  Treated in this light, design pattern would be any processes that have been previously known to work for certain problems. In certain domains, the process could be proved mathematically or are based on certain set of axioms or theories. In our case and at present our processes are not mathematically based, however, the processes are known to work based on previous experience. I think you get the idea now.

How would you define an object to use the object?
Alternatively, we can rephrase the question as to what are the various ways in which we can refer to an object within a code? There are three ways of doing this
1.     Using the class  - e.g. ClassA varA;
2.     Using the base class - e.g. BaseClassA varA;
3.     Using the interface - e.g. InterfaceA varA;
Here the assumption for point 2 is that ClassA extends BaseClassA. For point 3, we assume ClassA implements InterfaceA.

What does an external system see within an object?
Now that we have said about the external system let us go back to our example to show an important viewpoint. Let us say an object has methods m1, m2, m3 apart from the constructor of the object. Let us suppose (say) Interface1 has only one method m1, Interface2 has only two methods m1 and m3 while Interface3 has all the three methods m1, m2 and m3. Further, assume our class in consideration (say) ClassA implements only Interface2 and Interface3. Note that though ClassA has method m1, it does not mean it implements Interface1 unless it explicitly does so in the code. Now consider an external system which refers to the objects of ClassA by Interface2, in this case, the external system will not see or know the presence of method m3 within the object even though it is present. Seen in this way Interfaces are a means of hiding methods within a class like access restrictions is for a variable. It also means an object may have multiple methods but only those would be visible to an external system which is defined by the interface that the external system is using to refer to the object.


What is an abstraction?
This term is quite hard to understand at first. There is a dedicated page for this on the Wikipedia, however, that page may not be of much help in understanding what it is (true to its nature of being abstract), certainly it will make your understanding about abstraction more concrete provided you already know about abstraction, but that is if you know!. So here is the working definition; an abstraction is a model. And what is a model? Again a working definition would be; a model is an easy way of conveying ideas about a complex thing. Next point is how would we represent an abstraction? Or simply put how a person would represent a model in a programming language. Perhaps you guessed it, it is a class. So when we define a class representing say a car CarA, then CarA does not represent a real world car, you cannot drive it! So this CarA is a small representation of our real thing, which is what a model essentially is.  In this book, we refrain from using the word unless the lack of it causes ambiguity.

The point in time when we are designing:
This is not a term that we need to define. It is rather an important aspect that we need to be aware of when embarking on learning design patterns. The question being asked is about the time when the design comes into effect. It certainly depends upon the problem we are solving. The problem may arise when we are designing the solution or running the solution. Following are some educated guess of the possible situations.
1.     Design time – This refers to the time that the code is being created, i.e., you are creating some basic code which other will programmers will use to develop the system. An example of this could be you create an interface which others programmers will implement. Now this implementation could be in immediate future or in future when the code is released and required to be maintained during subsequent releases. The designer must have in mind both the immediate concerns and the future concerns. The future concerns can be accumulated based on experience or requirements assuming it exists.
2.     Compile time – Here the issue is within the interactions between classes or interfaces and these classes or interfaces already exists at the time of compilation. In this scenario, there cannot be objects or unknown classes or interfaces that the design may interact with.

3.     Runtime - Here the classes or interfaces already exists at the time of compilation plus classes or interfaces which could be dynamically loaded. In this scenario, there can be new objects or classes or interfaces that were not present during compile time and that interacts with the design. Here we can be concerned about runtime issues of (say) performance or restrict inclusion/behavior of new classes that may come into play.
4.     Post-release – Here we tackle the scenarios after the code is released and when subsequent teams have taken this code in part or entirety and are using them in their design.

Why is this important? This is important because often during learning design patterns the designer considers only the immediate issues while challenges of post release and maintenance aspects / problems are neglected. So considerations of post release / maintenance situation are also beneficial to any design in general.

The state of an object
The state of an object means the values of the different important subset of all variables within that object. Different because there could be multiple variables which define the state of an object. Important variables because, the object may have other variables also but it may not be included in the definition of the state of the object. Subset because not all variables may be used to define the state of an object.

Name conventions
All classes, interfaces and objects are suffixed with Class, Interface, and Object respectively. So if there was an existing class serving some purpose, we name it as ExistingClass. An object of this class is written as existingObject.

Italics are used for two purposes Firstly, for forming questions that are asked in between so that we are able to discuss the situation before we delve into the answers. Secondly, it is used for words, where we are not referring to the literal meaning but to the contextual meaning or laying emphasis on the word. All methods are suffixed with parenthesis. Methods do not have the suffix method as we are using parenthesis to denote this.

Please note, this is not the standard way of naming, it is used for the sake of making the explanation very lucid.


The sub-headings used in the chapters
Each chapter has the following sub-headings
Stage – In this section, we set the scene, we identify the situation. Often when this is very evident or there is nothing specific, this section is ignored.
Requirement – In this section, we identify and define the requirement.
Discussion – In this section, we identify the questions we face and discuss these questions. In this section, we try to capture the thought process which is essential to understand the design patterns. The discussions lead us to the solution. This is the core part of the book for each pattern.
Participants – In this section, for a given situation, we discuss some guidelines to identify which object/class should server which role.
Steps – In this section, we identify the generic few steps that we can apply in most cases to apply a design pattern.
Example code – In this section, links are given to internet repositories where we have examples of the code.
Further notes – In this section, we add few other viewpoints related to the design pattern, if required.






No comments:

Post a Comment