Object Oriented Programming: Implementation and usage

❝Differentiating two kinds of logic based on their application.❞
Contents

One of the first things to do, is to define clear notions of implementation logic and usage logic. The notions of ‘implementation’ and ‘usage’ will be used on multiple occasions in order to define a clear distinction. This definition is, of course, made in the context of object oriented design/programming. In no way is this post intended as a post on new information. It is simply meant to emphasize the notions as these are referenced in upcoming articles and I rely on these notions to make clear and strict distinctions and boundaries.

Firstly, this article relies on the notion of “internal state” as described in article Object Oriented Programming: Expectations - The Silent Third Characteristic. To be more specific, this article relies on the distinction that is made between the object’s actual state and the so called “expectations” that are set by the context of the application and provided to the object.

The notions implementation and usage exist solely because of the property Encapsulation of object oriented programming. This property dictates that access to internal state should be restricted. In order to make the restricted internal state useful, there must be select logic that is allowed access to this internal state to manage it.

This article is primarily concerned with the notions of implementation logic and usage logic. This is simply because the primary mechanism for expressing behavior is through logic. The reasoning is analoguous to that of the notions of implementation and usage in general.

Definition: usage logic

Usage logic is logic that uses an object (instance), given a reference to this object. Typically, this means that this logic can access non-encapsulated fields, such as public fields or package-private fields, and accessible logic. Usage logic is not implemented as a method of that object. The object is a given. Usage logic resides outside the class definition. As a consequence, usage logic is not tied to any single implementation, the type of the object it uses.

Definition: implementation logic

Implementation logic is logic that is directly related to a class, in the form of methods defined on that class. Implementation logic is in a privileged position. It is able to access internal state, i.e. fields and methods that are not accessible to usage logic. Logic is really only implementation logic if it accesses internal state.

Implementation logic leverages this privileged position in order to manage the internal state of the object. It is the sole responsibility of the implementation logic to make sure that the internal state remains consistent at all times.

If “implementation logic”, e.g. a method, does not access internal state (that cannot be accessed through the public interface of an object) then it is not implementation logic, just usage logic.

Recursive application of definition

This definition has a recursive nature. Any implementation logic is usage logic. Any logic we write in an object’s method is usage logic for the use of objects that are contained in the internal state of an object. These objects are used in the implementation logic, as part of the object’s internal state. Therefore, implementation logic is usage logic.

However, the reverse is not true. Usage logic is not implementation logic. Usage implies that this logic is not concerned with the implementation of the object. The object is already defined, including its implementation, and is ready to be used.

Minimizing the definition

The distinction between implementation and usage (logic) is determined by a single fact: whether or not internal state is accessed in a way that is not possible by usage logic.

Note that we also consider it implementation logic, if internal state is accessed “by proxy” through another method with restricted access (private).

What type of logic for methods?

In light of completing the distinction of usage logic and implementation logic, we look at the (local) state - local variables - in methods. How could we apply the minimized definition to the local logic and state of methods?

Methods contain the logic that connects the internal state of an object and the “outside world”. Depending on the purpose for which this logic is used, it supports usage logic or implementation logic. On the level of a method body, there is no notion of encapsulation, there is no need for a distinction between ‘usage’ and ‘implementation’. That is why logic inside the method has no inherent purpose. It is “just” the logic that connects other (implementation) logic.

As an example, let’s look at the logic that evaluates the value of an input parameter. The logic that executes the evaluation is clearly not accessing internal state. However, it is part of the logic that ensures internal state consistency. This is an example of “local” logic in service of the internal state. Removing this logic would result in failure to keep consistency in certain use cases.

Side-notes

In some programming languages, the distinction of usage and implementation is supported by the programming language’s type system. Support by the programming language is certainly convenient, however it is primarily a pattern. Even if it is not supported, then the distinction can still be made and the advantages are still there.

In languages such as Python, all state can be accessed by any logic, from any location. There is however the (informal) agreement that fields which are prefixed with ‘_’ should be treated as if they were unaccessible. Any usage logic that, nevertheless, does access this internal state may break at any time as code evolves. They are not part of the public interface. This is internal state by convention.


This post is part of the Object Oriented Programming series.
Other posts in this series: