Friday, 13 November 2020

Abstraction function, representation invariant

Abstraction Function & Rep invariant

The abstraction functions map values in a class to the abstract concept's required values. The representation invariants are those values that satisfy the abstraction function. By asserting the abstraction function we create the link (abstraction) from ints and string to our concept. This can be seen as giving the class meaning.

The abstraction funtion is like a filter that only allows values past which correctly describe the abstract concept.
Figure 1 - RatNum ADT


Below ZeroNumber is the concept we want to create. We represent it with a float however the concept requires that it only represents the number 0. Therefore we assert the abstraction function on the inValue and discard any values which are not rep invariants, this results in our classes concept (of being zero) being enforced.

class ZeroNumber {
    ZeroNumber(float inValue) {
        assert(inValue == 0.0f);     (2. Assertion for rep invariants)
        value = inValue;
    float value;  (1. Representation)

The abstraction function here is that the ZeroNumber class must be a number that can only be 0.

The rep invariants here are all values of (inValue) that are 0.0f.  In order for abstration function to hold the assertion (2) must hold since only rep invariants are allowed.


  • Object-oriented Software Construction, 1st Edition Bertrand Meyer

Tuesday, 10 November 2020

Object interface design - telling it to do something vs doing something to it

 An object represents a concept otherwise known as a "thing" or noun. Traditionally, we're taught that you can create an object then tell it what to do, however, this design (coming from Alan Kay) actually results in a mess of global state (which is the usual complaint about OOP). A more appropriate view is a little more complicated, we can create an object but we must define what we can do TO it.

For example you can Squeeze an Orange, therefore the object Orange has the Squeeze method. Traditionally it would be modelled as Person.Squeeze(Orange) however, here you aren't actually doing something TO the person object you are telling the person to do SOMETHING.

Friday, 6 November 2020

Mixing DDD , OOP and Modularity

The world map is a model of the Earth, it tries to solve a specific problem of planning shipping routes. As you can see Greenland is much much bigger than it is in reality, but this is because the purpose of the map is to find angles to sail, not to display the relative sizes of parts of the world. This is the most important concept for DDD because when we write software (using OOP in particular, more on this later) we are actually solving a problem by creating a model (since OOP based upon concepts and 'real things')  

For example when creating a program that models an air conditioning fan (it could be anything, a network, architecture, command processor) we need to find out what problem exactly we are trying to solve with the model. You can try to model the fan taking into account everything such as its weight, colour, year of purchase.etc but if you place a problem ontop of the model, you can really simplify your model down to an elegant solution. This is very important since software complexity is the major battle we have when creating programs.

In software we aim to create highly modular programs. We do this because it makes the software easier to create and maintain since we only have to think about a small set of things at a time.

Using the OOP paradigm, objects are supposed replicate real-life things (as Bertrand Meyer puts) as a "cousin twice removed" from reality. So, to modularize our OOP programs into simplified models provides a perfect match. 

  1. OOP for modelling concepts as objects.
  2. Models made from objects for solving a problem.
  3. Models divided into contexts to modularize our software.

Some links

Here is the talk Eric gives that explains it:

It's very difficult to summarise such a large topic but here are some links that explain the concepts.



Tuesday, 3 November 2020

OOP Tell dont ask and SRP


Tell dont ask and SRP seem to be conflicting principles, one says to make the object do the work and the other says that each object should only change for one reason (meaning it must be responsible for 1 logical part). So how do we design our programs to conform to both of these principles when an object theoretically does more than one thing?

Protected state, released state

Tell don't ask is actually about querying the state an object, making a decision on that queries state, and then changing the state of that object. So its not saying that you can't query the objects, but just that state changes must happen from within. In relation to Commands and Queries, Queries cannot change the internal state or release write-access to any of the internal state which fits with the tell don't ask principle.

Creating tiny objects

The SRP is about making each object do one thing, it is self explanitory in that a single object must have a defined singular purpose. Often it requires a very high level of granularity which can be found by using very specific bounded contexts e.g. namespaces/nested classes.

Well formed objects, well formed designs

We can combine both together by recognizing that the Tell-Dont-Ask does not mean that you cannot query data from it. So we can create small, axiomatic objects that can be queried by other small objects for the information they need.

Shopping for an objects interface

One problem is that its hard to decide what should be exported by the object and what shouldn't. There are many opinions on how it should be done, but, i find that Bertrand Meyers explanation is most mathematically sound. . The subject is huge and there are hundreds of sources of information from everywhere!

The difference between class and object.

 The difference between class and object is subtle and misunderstood frequently. It is important to understand the difference in order to wr...