CSC/ECE 517 Fall 2009/wiki3 19 rn: Difference between revisions
(34 intermediate revisions by one other user not shown) | |||
Line 5: | Line 5: | ||
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 (computing)|attribute]], precomputed [[Property (programming)|property]], or [[Method (computer science)|method]]/[[query]]. | 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 (computing)|attribute]], precomputed [[Property (programming)|property]], or [[Method (computer science)|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. | 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''' = | = '''UAP Example''' = | ||
Line 43: | Line 43: | ||
'''The Languages that don't support UAP are:''' | '''The Languages that don't support UAP are:''' | ||
* Ada | |||
* Java | * Java | ||
* C # | * C # | ||
Line 48: | Line 49: | ||
* Perl | * Perl | ||
* Small Talk | * Small Talk | ||
[[Image:Uap.png]] | |||
'''Explanation:''' As we can see in the figure, in the languages that do not support UAP, the method balance has to be called in a specific manner, depending upon its prototype of the method in the class in which it is defined. Where as in Eiffel, a language that supports UAP, the specific details of balance are not important to the function call. | |||
= '''Languages Supporting UAP WITH EXAMPLES''' = | = '''Languages Supporting UAP WITH EXAMPLES''' = | ||
Line 56: | Line 61: | ||
class Foo | class Foo | ||
attr_reader :x | attr_reader :x | ||
def initialize(x) | def initialize(x) | ||
Line 64: | Line 69: | ||
return @x * @x | return @x * @x | ||
end | end | ||
end | end | ||
<pre> | |||
y = Foo.new(2) | y = Foo.new(2) | ||
puts y.x | puts y.x | ||
puts y.squared_x | puts y.squared_x | ||
</pre> | |||
Output for Above Example: | |||
<pre> | <pre> | ||
2 | 2 | ||
Line 76: | Line 83: | ||
</pre> | </pre> | ||
Note how even though <code>x</code> is an attribute and <code>squared_x</code> is a parameterless method call, they are accessed the same way. | '''Observation:''' Note how even though <code>x</code> is an attribute and <code>squared_x</code> is a parameterless method call, they are accessed the same way. | ||
=== [[Python (programming language)|Python]] === | === [[Python (programming language)|Python]] === | ||
The following example uses python properties. | The following example uses python properties. | ||
< | <pre> | ||
class Foo(object): | class Foo(object): | ||
def __init__(self, x): | def __init__(self, x): | ||
Line 99: | Line 106: | ||
x = property(getx,setx, doc="x attribute of Foo object") | x = property(getx,setx, doc="x attribute of Foo object") | ||
squared_x = property(getsquared_x, doc="getter for squared x") | squared_x = property(getsquared_x, doc="getter for squared x") | ||
</pre> | |||
<pre> | |||
y = Foo(2) | y = Foo(2) | ||
print y.x | print y.x | ||
print y.squared_x | print y.squared_x | ||
</ | </pre> | ||
Outputs for the Above Example | |||
<pre> | <pre> | ||
2 | 2 | ||
4 | 4 | ||
</pre> | </pre> | ||
[[Python (programming language)#Objects|Python properties]] may be used to allow a method | '''Observation:''' [[Python (programming language)#Objects|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 | 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 single notation for both attribute access and method invocation (method invocation syntax), | ||
Line 118: | Line 128: | ||
=== [[Php|PHP]] === | === [[Php|PHP]] === | ||
< | <pre> | ||
class Foo{ | class Foo{ | ||
private $x; | private $x; | ||
Line 134: | Line 144: | ||
} | } | ||
} | } | ||
</pre> | |||
<pre> | |||
$y = new Foo(2); | $y = new Foo(2); | ||
echo $y->x(); | echo $y->x(); | ||
echo $y->squared_x(); | echo $y->squared_x(); | ||
</ | </pre> | ||
Outputs for the above Example: | |||
<pre> | <pre> | ||
2 | 2 | ||
Line 145: | Line 158: | ||
</pre> | </pre> | ||
Observation: There are many other ways to achieve the same functionality in PHP, for example making <code>x</code> <code>public</code> and accessing it directly or using magic methods <code>function __get($variable)</code> | '''Observation:''' There are many other ways to achieve the same functionality in PHP, for example making <code>x</code> <code>public</code> and accessing it directly or using magic methods <code>function __get($variable)</code> | ||
= '''Languages NOT Supporting UAP WITH EXAMPLES''' = | = '''Languages NOT Supporting UAP WITH EXAMPLES''' = | ||
=== [[Java programming language|Java]] === | |||
import java.util.* ; | import java.util.* ; | ||
class BankAccount { | class BankAccount { | ||
Line 169: | Line 182: | ||
} | } | ||
When looking at the code deposits.size(), the client can immediately see that deposits is an attribute (a “field” in Java terminology) and that size is a routine of class ArrayList (a “method” in Java terminology) because there is no opening and closing parentheses to access attributes whereas parentheses are compulsory for routine calls. This policy breaks the principle of Uniform Access; clients should not know whether a service is implemented by computation (routine) or by storage (attribute). | '''Observation:''' When looking at the code deposits.size(), the client can immediately see that deposits is an attribute (a “field” in Java terminology) and that size is a routine of class ArrayList (a “method” in Java terminology) because there is no opening and closing parentheses to access attributes whereas parentheses are compulsory for routine calls. This policy breaks the principle of Uniform Access; clients should not know whether a service is implemented by computation (routine) or by storage (attribute). | ||
=== [[Small Talk programming language|Small Talk]] === | |||
In SmalltalkLanguage, UAP is not supported. But since variables are local to objects, you only have to worry about the difference within that object's methods, and nowhere else. By insisting that every variable access (even local ones) be through a getter/setter, UAP can be supported in Smalltalk. This is also extraordinarily helpful if the object in question is persistent, and therefore subject to various db synchronization/transaction issues. | |||
= '''ADVANTAGES OF UAP''' = | = '''ADVANTAGES OF UAP''' = | ||
Line 179: | Line 196: | ||
*The Uniform Access Principle seeks to eliminate this needless coupling. A language supporting the Uniform Access Principle does not exhibit any notational differences between accessing a feature regardless of whether it is an attribute or a function. Thus, in our earlier example, access to bar would always be in the form of foo.bar, regardless of how bar is implemented. This makes clients of Foo more resilient to change. | *The Uniform Access Principle seeks to eliminate this needless coupling. A language supporting the Uniform Access Principle does not exhibit any notational differences between accessing a feature regardless of whether it is an attribute or a function. Thus, in our earlier example, access to bar would always be in the form of foo.bar, regardless of how bar is implemented. This makes clients of Foo more resilient to change. | ||
= | = '''DISADVATAGES OF UAP''' = | ||
Dis-advantage of using UAP is as follows:- | |||
The UAP is only appropriate in a system that supports [http://en.wikipedia.org/wiki/Information_hiding information hiding] to the full (and in a way, implies this), as otherwise a client would be entirely justified in trying to perform an operation such as | |||
x.f = y; | |||
Where f is in fact a routine defined on x! Whereas if they are aware that everything in the public interface of a class is a function, they would not be justified in trying to perform such an action. | |||
='''SUMMARY'''= | |||
The article discusses about uniform access principle by expanding the current wiki article. The features discussed include the necessity for UAP, the Languages that support it, specific examples for the same and the advantages of the principle. Also we continue to discuss the languages that do not support this principle with reasons and a specific example in Java supporting it. Disadvantage of the principle has also been cited as a countervailing argument. | |||
= '''GLOSSARY''' = | |||
[http://en.wikipedia.org/wiki/Information_hiding Information Hiding]: Information hiding in computer science is the principle of segregation of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change). | |||
='''REFERENCES'''= | |||
* http://en.wikipedia.org/wiki/Uniform_access_principle | |||
* [http://c2.com/cgi/wiki?UniformAccessPrinciple The UniformAccessPrinciple on the c2 wiki] | * [http://c2.com/cgi/wiki?UniformAccessPrinciple The UniformAccessPrinciple on the c2 wiki] | ||
* http://www.eiffel.com/general/monthly_column/2005/Sept_October.html | * http://www.eiffel.com/general/monthly_column/2005/Sept_October.html | ||
* http://everything2.com/title/Uniform+Access+Principle | |||
* http://www.jvoegele.com/software/langcomp.html | |||
* http://en.wikipedia.org/wiki/Information_hiding | |||
Latest revision as of 17:11, 21 November 2009
PROBLEM STATEMENT
The principle that an access (read or write) to a feature of an object should be written the same whether the feature is an instance variable or method. Look at the current Wikipedia article on the subject and expand on it. Consider the reason for this principle and try to find countervailing arguments against it. Note that since you are expanding on the current article, it is fine to lift text that is in the Wikipedia article right now.
INTRODUCTION
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
EXPLAINATION OF EXAMPLE
Say that bar is a feature of a class named Foo. For languages that do not support the Uniform Access Principle, the notation used to access bar differs depending on whether it is an attribute (storage) or a function (computation). For example, in Java you would use foo.bar if it were an attribute, but you would use foo.bar() if it were a function. Having this notational difference means that users of Foo are exposed to unnecessary implementation details and are tightly coupled to Foo. If bar is changed from attribute to method (or vice versa), then any users of Foo must also be changed.
UAP SUPPORT IN LANGUAGES
The Languages that Support UAP are:
- Eiffel
- Ruby
- Visual Basic
The Languages that don't support UAP are:
- Ada
- Java
- C #
- C++
- Perl
- Small Talk
Explanation: As we can see in the figure, in the languages that do not support UAP, the method balance has to be called in a specific manner, depending upon its prototype of the method in the class in which it is defined. Where as in Eiffel, a language that supports UAP, the specific details of balance are not important to the function call.
Languages Supporting UAP WITH 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
Output for Above Example:
2 4
Observation: 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
Outputs for the Above Example
2 4
Observation: 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();
Outputs for the above Example:
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)
Languages NOT Supporting UAP WITH EXAMPLES
Java
import java.util.* ; class BankAccount { …. public int balance(){ int depositSum = 0; int withdrawalSum = 0; for (int i = 0; i < deposits.size(); i++){ depositSum = depositSum + ((Integer)deposits.get(i)).intValue(); } for (int i = 0; i < withdrawals.size(); i++){ withdrawalSum = withdrawalSum + ((Integer) withdrawals.get(i)).intValue(); } return depositSum – withdrawalSum; } … protected ArrayList deposits; protected ArrayList withdrawals; }
Observation: When looking at the code deposits.size(), the client can immediately see that deposits is an attribute (a “field” in Java terminology) and that size is a routine of class ArrayList (a “method” in Java terminology) because there is no opening and closing parentheses to access attributes whereas parentheses are compulsory for routine calls. This policy breaks the principle of Uniform Access; clients should not know whether a service is implemented by computation (routine) or by storage (attribute).
Small Talk
In SmalltalkLanguage, UAP is not supported. But since variables are local to objects, you only have to worry about the difference within that object's methods, and nowhere else. By insisting that every variable access (even local ones) be through a getter/setter, UAP can be supported in Smalltalk. This is also extraordinarily helpful if the object in question is persistent, and therefore subject to various db synchronization/transaction issues.
ADVANTAGES OF UAP
Some of the Advantages of using UAP are as follows:-
- Hiding implementation from the client (i.e. hiding the fact a service is implemented by computation or by storage) provides flexibility. It is possible to change the implementation (for example, decide to use an attribute rather than a routine) at no cost for the clients. The supplier does not have to tell its clients about this change; the client code will continue to work.
- The Uniform Access Principle seeks to eliminate this needless coupling. A language supporting the Uniform Access Principle does not exhibit any notational differences between accessing a feature regardless of whether it is an attribute or a function. Thus, in our earlier example, access to bar would always be in the form of foo.bar, regardless of how bar is implemented. This makes clients of Foo more resilient to change.
DISADVATAGES OF UAP
Dis-advantage of using UAP is as follows:-
The UAP is only appropriate in a system that supports information hiding to the full (and in a way, implies this), as otherwise a client would be entirely justified in trying to perform an operation such as
x.f = y;
Where f is in fact a routine defined on x! Whereas if they are aware that everything in the public interface of a class is a function, they would not be justified in trying to perform such an action.
SUMMARY
The article discusses about uniform access principle by expanding the current wiki article. The features discussed include the necessity for UAP, the Languages that support it, specific examples for the same and the advantages of the principle. Also we continue to discuss the languages that do not support this principle with reasons and a specific example in Java supporting it. Disadvantage of the principle has also been cited as a countervailing argument.
GLOSSARY
Information Hiding: Information hiding in computer science is the principle of segregation of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from extensive modification if the design decision is changed. The protection involves providing a stable interface which protects the remainder of the program from the implementation (the details that are most likely to change).
REFERENCES
- http://en.wikipedia.org/wiki/Uniform_access_principle
- The UniformAccessPrinciple on the c2 wiki
- http://www.eiffel.com/general/monthly_column/2005/Sept_October.html
- http://everything2.com/title/Uniform+Access+Principle
- http://www.jvoegele.com/software/langcomp.html
- http://en.wikipedia.org/wiki/Information_hiding