Uniform access principle
Encyclopedia
The Uniform Access Principle was put forth by Bertrand Meyer
. It states "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation." This principle applies generally to object-oriented programming languages. In simpler form, it states that there should be no difference between working with an attribute
, precomputed property
, or method
/query
.
While most examples focus on the "read" aspect of the principle, Meyer shows that the "write" implications of the principle are harder to deal with in his monthly column on the Eiffel programming language
official website.
Going the reverse way (from method to simple attribute) really wasn't a problem, as one can always just keep the function and have it simply return the attribute value.
Meyer recognized the need for software developers to write code in such a way as to minimize or eliminate cascading changes in code that result from changes which convert an object attribute to a method call(or vice versa). For this he developed the Uniform Access Principle.
Many programming languages do not strictly support the UAP but do support forms of it. Properties, which are provided in a number of programming languages, address the problem Meyer was addressing with the UAP in a different way. Instead of providing a single uniform notation, properties provide a way to invoke a method of an object while using the same notation as is used for attribute access. The separate method invocation syntax is still available.
When executed, should display :
Whether or not Foo.bar(5) invokes a function or simply sets an attribute is hidden from the caller.
Likewise whether Foo.bar simply retrieves the value of the attribute, or invokes a function
to compute the value returned, is an implementation detail hidden from the caller.
If the language uses the attribute syntax the syntax may look like this.
Again, whether or not a method is invoked, or the value is simply assigned to an attribute is hidden
from the calling method.
Now the Egg class could be defined as follows
The above initial code segment would work fine with the Egg being defined as such. The Egg
class could also be defined as below, where color is instead a method. The calling code would
still work, unchanged if Egg were to be defined as follows.
Note how even though
in the next, the interface to the class remains the same. The person maintaining the Egg class can switch from one form to the other without fear of breaking any caller's code.
Ruby enforces UAP, the
for generating accessor/setter methods for
to be invoked with the same syntax as accessing an attribute. Whereas Meyer's UAP would have
a single notation for both attribute access and method invocation (method invocation syntax),
a language with support for properties still supports separate notations for attribute
and method access. Properties allow the attribute notation to be used, but to hide the
fact that a method is being invoked instead of simply retrieving or setting a value.
In the strict sense, Python does NOT follow the UAP because there is a syntax difference
between normal method invocations and attribute access.
In Python, we may have code that access an object as follows
A Egg object could be defined such that weight and color are simple attributes as in the following
Or the Egg object could use properties, and invoke methods instead
Regardless of which way Egg is defined, the calling code can remain the same. The implementation of Egg can switch from one form to the other without affecting code that uses the Egg class. Languages which implement the UAP have this property as well.
C++ has neither the UAP nor properties, when an object is changed such that an attribute (color) becomes a pair of functions (getA, setA). Any place in that uses an instance of the object and either sets or gets the attribute value ( x = obj.color or obj.color= x) must be changed to invoke one of the functions. ( x = obj.getColor or obj.setColor(x)). Using templates and operator overloading, it is possible to fake properties, but this is more complex than in languages which directly support properties. This complicates maintenance of C++ programs. Distributed libraries of C++ objects must be careful about how they provide access to member data.
Bertrand Meyer
Bertrand Meyer is an academic, author, and consultant in the field of computer languages. He created the Eiffel programming language.-Education and academic career:...
. It states "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation." This principle applies generally to object-oriented programming languages. In simpler form, it states that there should be no difference between working with an attribute
Attribute (computing)
In computing, an attribute is a specification that defines a property of an object, element, or file. It may also refer to or set the specific value for a given instance of such....
, precomputed property
Property (programming)
A property, in some object-oriented programming languages, is a special sort of class member, intermediate between a field and a method. Properties are read and written like fields, but property reads and writes are translated to get and set method calls...
, or method
Method (computer science)
In object-oriented programming, a method is a subroutine associated with a class. Methods define the behavior to be exhibited by instances of the associated class at program run time...
/query
Information retrieval
Information retrieval is the area of study concerned with searching for documents, for information within documents, and for metadata about documents, as well as that of searching structured storage, relational databases, and the World Wide Web...
.
While most examples focus on the "read" aspect of the principle, Meyer shows that the "write" implications of the principle are harder to deal with in his monthly column on the Eiffel programming language
Eiffel (programming language)
Eiffel is an ISO-standardized, object-oriented programming language designed by Bertrand Meyer and Eiffel Software. The design of the language is closely connected with the Eiffel programming method...
official website.
Explanation
The problem being addressed by Meyer involves the maintenance of large software projects or software libraries. Sometimes when developing or maintaining software it is necessary, after much code is in place, to change a class or object in a way that transforms what was simply an attribute access into a method call. Programming languages often use different syntax for attribute access and invoking a method, (e.g. obj.something versus obj.something). The syntax change would require, in popular programming languages of the day, changing the source code in all the places where the attribute was used. This might require changing source code in many different locations throughout a very large volume of source code. Or worse, if the change is in an object library used by hundreds of customers, each of those customers would have to find and change all the places the attribute was used in their own code and recompile their programs.Going the reverse way (from method to simple attribute) really wasn't a problem, as one can always just keep the function and have it simply return the attribute value.
Meyer recognized the need for software developers to write code in such a way as to minimize or eliminate cascading changes in code that result from changes which convert an object attribute to a method call(or vice versa). For this he developed the Uniform Access Principle.
Many programming languages do not strictly support the UAP but do support forms of it. Properties, which are provided in a number of programming languages, address the problem Meyer was addressing with the UAP in a different way. Instead of providing a single uniform notation, properties provide a way to invoke a method of an object while using the same notation as is used for attribute access. The separate method invocation syntax is still available.
UAP Example
If the language uses the method invocation syntax it may look something like this.
//Assume print displays the variable passed to it, with or without parens
//Set Foo's attribute 'bar' to value 5.
Foo.bar(5)
print Foo.bar
When executed, should display :
5
Whether or not Foo.bar(5) invokes a function or simply sets an attribute is hidden from the caller.
Likewise whether Foo.bar simply retrieves the value of the attribute, or invokes a function
to compute the value returned, is an implementation detail hidden from the caller.
If the language uses the attribute syntax the syntax may look like this.
Foo.bar = 5
print Foo.bar
Again, whether or not a method is invoked, or the value is simply assigned to an attribute is hidden
from the calling method.
Ruby
Consider the followingNow the Egg class could be defined as follows
The above initial code segment would work fine with the Egg being defined as such. The Egg
class could also be defined as below, where color is instead a method. The calling code would
still work, unchanged if Egg were to be defined as follows.
Note how even though
color
looks like an attribute in one case and a pair of methodsin the next, the interface to the class remains the same. The person maintaining the Egg class can switch from one form to the other without fear of breaking any caller's code.
Ruby enforces UAP, the
attr_accessor :color
only acts as syntactic sugarSyntactic sugar
Syntactic sugar is a computer science term that refers to syntax within a programming language that is designed to make things easier to read or to express....
for generating accessor/setter methods for
color
. There is no way in Ruby to retrieve an instance variable from an object without calling a method on it, making Ruby a language which enforces the UAP.Python
Python properties may be used to allow a methodto be invoked with the same syntax as accessing an attribute. Whereas Meyer's UAP would have
a single notation for both attribute access and method invocation (method invocation syntax),
a language with support for properties still supports separate notations for attribute
and method access. Properties allow the attribute notation to be used, but to hide the
fact that a method is being invoked instead of simply retrieving or setting a value.
In the strict sense, Python does NOT follow the UAP because there is a syntax difference
between normal method invocations and attribute access.
In Python, we may have code that access an object as follows
A Egg object could be defined such that weight and color are simple attributes as in the following
Or the Egg object could use properties, and invoke methods instead
Regardless of which way Egg is defined, the calling code can remain the same. The implementation of Egg can switch from one form to the other without affecting code that uses the Egg class. Languages which implement the UAP have this property as well.
C++ has neither the UAP nor properties, when an object is changed such that an attribute (color) becomes a pair of functions (getA, setA). Any place in that uses an instance of the object and either sets or gets the attribute value ( x = obj.color or obj.color= x) must be changed to invoke one of the functions. ( x = obj.getColor or obj.setColor(x)). Using templates and operator overloading, it is possible to fake properties, but this is more complex than in languages which directly support properties. This complicates maintenance of C++ programs. Distributed libraries of C++ objects must be careful about how they provide access to member data.
See also
- The UniformAccessPrinciple on the c2 wiki
- http://www.eiffel.com/general/monthly_column/2005/Sept_October.html