14. Representative and non-representative parts

In this chapter, we discuss representative and non-representative parts of a program with respect to modeling a given domain.

A primary focus of this book has been to emphasize that programming is modeling in the sense that programming is about creating a model of the relevant aspects of the application domain. This implies that one should attempt to represent descriptions of phenomena and their properties by corresponding language elements in the program.

There will, however be elements in a given program that do not relate to phenomena or concepts from the application domain. This is due to the fact that it must be possible to execute the program on a computer. To do this, part of a program will be elements that implements the parts that relate to the model of the application domain.

The part of the program that describes phenomena and concepts from the application domain is called the representative part. The part which is not representative is called non-representative.

Non-representative parts of class Account

In the following we consider class Account in the bank domain with respect to representative and non-representative parts.

Representation of concepts and phenomena in the bank domain

In the previous versions of Account there is at a first glance no attributes that cannot be considered representative. All of owner, balance, interestRate, deposit, withdraw, etc. are meaningful in the bank domain.

We originally introduced assignments like:

account_1010.balance := 523.07

and said that such an assignment may be considered a deposit on the account. And further assignments like:

account_1010.balance := account_1010.balance + 200
account_1010.balance := account_1010.balance - 300

may also be considered deposits or withdrawals.

However, we have methods deposit and withdraw, which are supposed to represent deposits and withdrawals of money on the account. And from a  modeling point of view these conflict with assigning to balance directly.

In addition, there is more to a deposit and withdraw than just updating balance. In section , we introduced class Transactions and an object transaction. which keeps track of deposits and withdrawals on a given account. We would thus want to prevent access to balance from outside the Account-objects.

However, we do want to be able to read/print the current balance of a given account. In addition, we may want to log that someone has read the balance of an account.

We may handle this by adding a method getBalance to the class Account:

getBalance -> bal: var float: transact
   bal := balance 
   theTransaction.what := “getBalance”

The above considerations also apply to the variable interestRate. Here we do not want to be able to manipulate interestRate directly from outside an account just as update of an interesRate may imply more actions to be carried out. This may include informing the customer about the change.

We may thus introduce a method getInterestRate like getBalance and we may introduce methods setInterestRate and getInterestRate.

In the following we introduce language mechanism for controlling the accessibility to attributes.

Måske bruge class Set som ex?

Visibility mechanisms

Here we introduce some language mechanisms that may be used to separate the representative elements from the non-representative elements. The language elements are called access modifiers and they may specify the accessibility of attributes of an object. Access modifiers define the scope and visibility of these attributes in the code. This means that the programmer may specify to what extent a local data-item, method or class may be accessed in other parts of the code.

The most common types of access modifiers are public, private, and protected, but some languages support more as is the case for qBeta (see below). Each access modifier provides different levels of access.

Kan vi finde et andet navn for protected – siger jo ikke noget om hvad det betyder og begyndere kan have problemer med at huske forskellen mellem private og protected. OLM: i qbeta hedder den pt faktisk %publicinsub – bedre med %visibleinsub
Og vi skal også have et andet navn for domain,

%private

As a first example, we will show how to use the access modifier %private to protect balance and interestRate of Account objects:

class Account(owner: var String):
   addInterest: -"-
   deposit(amount: var float): -"-
   withdraw(amount: var float) -> newB: var float: -"-
   getBalance -> bal: var float: -"-
   getInterestRate -> iRate: var float: ...
   setInterestRate(iRate: var float): ...
   %private
   balance: var float
   interestRate: var float

The access modifier %private before the declarations of balance and interestRate specfies that balance and interestRate may only be accessed within class Account.

Representative and non-representative parts of models in the bank domain

%protected

When using %private in class Account as above, no other classes or objects may acces balance and interestRate. However, this may be inconvenient for subclasses of Account like SavingsAccount, where we may add methods that manipulate these attributes.

The access modifier %protected may be used to specify that some attributes may only be accessed within a class and its subclasses.

Så protected er det samme som private for klassen den står i. OLM: ja – er det ikke det i SIMULA?

We may thus revise class Account as follows:

class Account:
   -"-
   %protected
   balance: var float
   interestRate: var float
class SavingsAccout: Account
   -- balance and interestRate may now be accessed here
   -"-
aClerk: obj
   -- balance and interestRate may not be accessed
   -"-

%public

For completeness, the access modifier %public may be used to specify that some attributes are visible outside the class/object-descriptor +++ her står der descriptor, mens ovenfor står der object; descriptor er vel det rigtige. However, %public is default in qBeta – if no access modifier is specified for some attributes they are visible outside the object-descriptor. Sometimes it may be useful to use %public if one prefer to have e.g. the private attributes appearing before the ones that are public. This is the case for the version of class Account below:

class Account:
   %protected
   balance: var float
   interestRate: var float
   %public
   addInterest: -"-
   -"-

Here balance and interestRate are declared in the beginning as %protected followed by the methods of the class – these are thus explicitly declared as %public.

%domain

Mangler så et eksempel med %domain.
2024-08-12: Men kræver at moduler er indført, så måske vi skal forklare den i kapitlet om moduler og så henvise til det?
Af de eksempler vi pt har er det kun ExpressionGrammar der er delt op i moduler på den måde at ExpressionGrammar har nested moduler expParser og expAST. Og der er ikke attributter i dem så det gir mening at de kune kan tilgås indenfor ExpressionGrammar.

Iøvrigt skal vi ha et bedre navn, da %domain jo ikke går på application domain.
Kan være noget med %module, men er i brug til inklusion af moduler, måske %in_module og %module_boundary


TopModule: module
   %module_boundary
   ...
   mod1: module
      ...
      %in_module
      foo: ...
      ...
   mod2: module
      ...
      %in_module
      bar: ...
      ... 


foo og bar er så synlige i TopModule og mod1 og mod2

Men lidt lange navne – har set på whole, aggregate, group, package, cluster, bundle, …
Måske %package, %package_boundary (eller blot %boundary)

Summary of access modifiers

In this section we summarize the description of access modifiers – we use the following sketchy example:

class T:
   ...
   %public
   X: var integer
   m(...):
      ...
   %private
   Y: var integer
   L: obj Set(integer)
   ...
   %protected
   Z: var integer
   S: ref Person
   ...
   %domain
   V: var real
   foo:
      ...
   ...

The class T is specified using the access modifiers %public, %private, %protected, and %domain.

An access modifier applies to all the attributes following the modifier, up to the next access modifier.

The next example shows a usage of class T where we have a T-object:

R: obj T
-- The access modifiers specify if we may acces the attributes
-- R.X, R.Y, R.Z, R.V, ...

In the next example, we have a subclass TT of T:

class TT: T
   -- Here the access modifiers above also specify if we may access
   -- X, Y, Z, V, ...

Public

The access modifier %public specifies that one or more attributes are accessible from outside the object-descriptor where it is declared.

In the above examples X and m may be accessed via R.x, R.m(...) and as X an m(...) in the subclass TT of T.

Private

The access modifier %private specifies that one or more attributes may only be accessed within the object-descriptor where they are declared.

This means that R.Y and R.L is not legal and that Y and L may not be accessed in the subclass TT.

Protected

The access modifier %protected is like %private except that the attributes may be accessed in subclasses of the class where they are declared.

This means that Z and S may not be accessed via R.Z and R.S but may be accessed in all subclasses of T.

Domain

The access modifier %domain specifies that one or more attributes can be accessed within a set of modules. This is specific to qBeta — see the section on modules. Java has a similar mechanism for packages.

Default

If no access modifier is specified, the default is %public.

Information hiding and encapsulation

As mentioned, access modifiers may be use to separate representative parts of a program from non-representative parts. The term information hiding is often used for a similar purpose. Information hiding is a software design principle that is used to limit the parts of a component that is accessible to its clients.

In the context of this book, we use the term component for module description?, class description?, or object-descriptor.

The primary goal of information hiding is to prevent extensive modification to clients whenever the implementation details of a component are changed. This is done by hiding implementation details that are not relevant for the use of a given component.

The term encapsulation is often used in connection to information hiding. One may think of information hiding is a design principle and encapsulation as a technical term. A component like a class is said to encapsulate attributes and hiding implementation details. A component hides information by encapsulating the information into a component which presents an interface

The term interface of a component is another important term in software design. The interface of a component is the set of attributes that are accessible by clients of the component. The attributes of a given component defined as %public thus constitutes the interface of the component. Clients of the interface of a component will access the component purely through its interface. This way, if the implementation changes, the clients do not have to change.

The term Application Programming Interface (API) is another common term. It refers to the interface of a component, but is most often used for software modules and/programs used by other modules or programs, but technically it is an interface.

In many schools of software design, it is a common design principle that the interface of a component should be restricted to a set of methods. Data-items are primarily considered implementation details and access to data-items should therefore be limited. In object-oriented design as advocated in this book, an interface may also include local classes of a component and/or part objects.

Information hiding, encapsulation and interface are technical terms of software design. They go hand inland with programming as modeling. One way of practicing information hiding s to make sure that only representative parts of a module are visible to clients and thus provides the interface. Non-representative parts correspond to implementation. Modules, classes and object-descriptors are language mechanisms for supporting encapsulation supplemented by access modifiers.

Skal vi sige mere om hvordan man kan praktisere information hiding?
Shall we mention abstraction barriers, layers, etc.
Tekset nedenfor er klip fra nettet der blot skal bruges om input

Information hiding serves as a criterion that can be used to decompose a system into modules. The principle is also useful for reducing coupling within a system.

A common use of information hiding is to hide the physical storage layout for data so that if it is changed, the change is restricted to a small subset of the total program. For example, if a three-dimensional point (xyz) is represented in a program with three floating-point scalar variables and later, the representation is changed to a single array variable of size three, a module designed with information hiding in mind would protect the remainder of the program from such a change.

This link has some guidelines for information hiding: https://embeddedartistry.com/fieldmanual-terms/information-hiding/