CSC/ECE 517 Fall 2009/wiki3 19 rn
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.
Many languages have various degrees of support for UAP, where some of the implementations violate the spirit of UAP. The inclusion of 'properties' in some programming languages is another way to address the problem that Meyer discusses. Properties don't provide a uniform notation, but they do make the call to the method which provides a service opaque.
UAP Example
If a language allows access to a variable via dot-notation and assignment
Foo.bar = 5 //Assigns 5 to the object variable "bar"
then these operations should be the same :
//Assume print displays the variable passed to it, with or without parens //Assume Foo.bar = 5 for now print Foo.bar print Foo.bar()
When executed, should display :
5 5
This allows the object to still hide information as well as being easy to access.
The same should be true for setting the data.
Foo.bar = 5 Foo.bar(5) //These should achieve the same goal
Language Examples
Ruby
class Foo
attr_reader :x
def initialize(x)
@x = x
end
def squared_x
return @x * @x
end
end
y = Foo.new(2)
puts y.x
puts y.squared_x
This outputs:
2 4
Note how even though x
is an attribute and squared_x
is a parameterless method call, they are accessed the same way.
Python
The following example uses python properties.
class Foo(object):
def __init__(self, x):
self.setx(x)
def getx(self):
return self.__x
def setx(self, x):
if type(x) != int:
raise ValueError('Not an integer')
self.__x = x
def getsquared_x(self):
return self.x * self.x
x = property(getx,setx, doc="x attribute of Foo object")
squared_x = property(getsquared_x, doc="getter for squared x")
y = Foo(2)
print y.x
print y.squared_x
This outputs:
2 4
Python properties may be used to allow a method 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 to invoke a method where that is desirable.
PHP
class Foo{
private $x;
function __construct($x){
$this->x = $x;
}
function x(){
return $this->x;
}
function squared_x(){
return $this->x * $this->x;
}
}
$y = new Foo(2);
echo $y->x();
echo $y->squared_x();
This outputs:
2 4
Observation: There are many other ways to achieve the same functionality in PHP, for example making x
public
and accessing it directly or using magic methods function __get($variable)