Uniform access principle
The uniform access principle of computer programming was put forth by Bertrand Meyer (originally in his book Object-Oriented Software Construction). 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."[1][2] This principle applies generally to the syntax of object-oriented programming languages. In simpler form, it states that there should be no syntactical difference between working with an attribute, pre-computed property, or method/query of an object. While most examples focus on the "read" aspect of the principle (i.e., retrieving a value), Meyer shows that the "write" implications (i.e., modifying a value) of the principle are harder to deal with in his monthly column on the Eiffel programming language official website.[3] ExplanationThe 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., Going the reverse way (from method to simple attribute) really was not 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 his 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 exampleIf 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 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. ProblemsHowever, UAP itself can lead to problems, if used in places where the differences between access methods are not negligible, such as when the returned value is expensive to compute or will trigger cache operations.[2] Language examplesPythonPython 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, but to hide the fact that a method is being invoked instead of simply retrieving or setting a value. As such, Python leaves the option of adherence to UAP up to the individual programmer. The built-in In Python, we may have code that access an """
>>> egg = Egg(4.0, "white")
>>> egg.color = "green"
>>> print(egg)
Egg(4.0, green)
"""
class Egg:
def __init__(self, weight, color) -> None:
self.weight = weight
self.color = color
def __str__(self) -> str:
return f"{__class__.__name__}({self.weight}, {self.color})"
Or the Egg object could use properties, and invoke getter and setter methods instead # ...(snip)...
class Egg:
def __init__(self, weight_oz: float, color_name: float) -> None:
self.weight = weight_oz
self.color = color_name
@property
def color(self) -> str:
'''Color of the Egg'''
return to_color_str(self._color_rgb)
@color.setter
def color(self, color_name: str) -> None:
self._color_rgb = to_rgb(color_name)
@property
def weight(self) -> float:
'''Weight in Ounces'''
return self._weight_gram / 29.3
@weight.setter
def weight(self, weight_oz: float) -> None:
self._weight_gram = 29.3 * weight_oz
# ...(snip)...
Regardless of which way RubyConsider the following y = Egg.new("Green")
y.color = "White"
puts y.color
Now the Egg class could be defined as follows class Egg
attr_accessor :color
def initialize(color)
@color = color
end
end
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. class Egg
def initialize(color)
@rgb_color = to_rgb(color)
end
def color
to_color_name(@rgb_color)
end
def color=(color)
@rgb_color = to_rgb(color)
end
private
def to_rgb(color_name)
.....
end
def to_color_name(color)
....
end
end
Note how even though Strictly speaking, Ruby does not follow Meyer's original UAP in that the syntax for accessing an attribute is different from the syntax for invoking a method. But here, the access for an attribute will always actually be through a function which is often automatically generated. So in essence, either type of access invokes a function and the language does follow Meyer's revised Uniform Access Principle. C#The C# language supports class properties, which provide a means to define public class Foo
{
private string _name;
// Property
public int Size
{
get; // Getter
set; // Setter
}
// Property
public string Name
{
get { return _name; } // Getter
set { _name = value; } // Setter
}
}
In the example above, class Omitting the Use of the properties employs the UAP, as shown in the code below. public Foo CreateFoo(int size, string name)
{
var foo = new Foo();
foo.Size = size; // Property setter
foo.Name = name; // Property setter
return foo;
}
C++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 ( JavaScriptJavaScript has had support for computed properties since 2009.[5] References
|
Portal di Ensiklopedia Dunia