Recipe 2.3. Creating
Properties That Behave As Methods
Problem
You want to use public properties that
behave like methods so you don't break encapsulation.
Solution
Use implicit getters and setters.
Discussion
As mentioned in Recipe
2.1, all properties should be declared as private or
protected. public properties are not a good idea
because of a principal called encapsulation. Good encapsulation is something
to strive for. It means that a class doesn't expose its internals
in a way that it can be easily broken; public properties
can enable developers to easily break a class or an instance of a
class. Consider the following simple example that uses a
public property:
package {
public class Counter {
public var count:uint;
public function Counter( ) {
count = 0;
}
}
}
You can then construct an instance of
Counter, and you can change the count property
value, as shown here:
var counter:Counter = new Counter( );
counter.count++;
However, what if the business rules of the
application state that a Counter should never exceed 100?
You can see that the Counter class with a public
count property makes it quite easy to break that rule.
One option is to use explicit getters and
setters, as in the following example:
package {
public class Counter {
private var _count:uint;
public function Counter( ) {
_count = 0;
}
public function getCount( ):uint {
return _count;
}
public function setCount(value:uint):void {
if(value < 100) {
_count = value;
}
else {
throw Error( );
}
}
}
}
Another option is to use implicit getters and
setters. Implicit getters and setters are declared as methods, but
they look like properties. The syntax for a getter is as
follows:
public function get name( ):Datatype {
}
The syntax for a setter is as follows:
public function set name(value:Datatype):void {
}
The following defines count with implicit getter
and setter methods:
package {
public class Counter {
private var _count:uint;
public function Counter( ) {
_count = 0;
}
public function get count( ):uint {
return _count;
}
public function set count(value:uint):void {
if(value < 100) {
_count = value;
}
else {
throw Error( );
}
}
}
}
You can then treat count as though it were a
public property:
counter.count = 5;
trace(counter.count);
See Also
Recipe
2.1
|