Why Properties matter : Uniform Access Principle
Learning a new language has various side-effects. Old habits are questioned, good practices are reinforced while bad habits come to light. By re-learning programming principles in a new syntax, in that strange new world (IDE, Syntax, etc..) you learn something new about your favorite languages – and often yourself.
I started off in C++ moved to Java then C# and most recently have begun working w/ Scala. In the book, Programming Scala by Dean Wampler & Alex Payne, the Uniform Access Principle was described & named.
So what is all the hubbub about Uniform Access Principle?
Clients read and write field values as if they are publicly accessible, even though in some case they are actually calling methods
In short, from the outside, a method or field is indistinguishable.
Why is the Uniform Access Principle important?
Classes can interchange methods and fields without affecting the classes that use them.
Language support of UAP?
Sadly, few languages (that I know) support UAP fully.
JAVA
Java does not support UAP, either a class has a field or bean properties. (getter/setter).
public class Employee{
private String m_name;
public String getName() {
return m_name;
}public void setName(String name) {
return m_name;
}}
C#
C# does not fully support UAP, but fields & properties are partially indistinguishable. Here are the short comings:
- interfaces can not contain fields, only properties. [ propName {get;set;} vs fieldname; ]
- fields can be passed by ref or out but not properties (see example project)
class Program
{
static void Main(string[] args)
{
var e = new Employee();
e.Name = "Alan Huffman";PrintRef(ref e.Name);
var e2 = new EmployeeProp();
e2.Name = "John Dobson";// COMPILATION ERROR
// can not pass a property by reference
PrintRef(ref e2.Name); // *** Compilation errorpublic static void PrintRef(ref String str){
Console.WriteLine(str);
}
}
public interface IEmployee
{
String Name;// if we change the field into a property, we get an error on Employee class below
String Name {get;set;}
}public class Employee : IEmployee
// if the interface defines a property and we try to implement w/ a field
public String Name;
}
public class EmployeeProp : IEmployee
{
public string Name { get; set; }
}
SCALA
SCALA does support UAP, essentially providing abstraction at a language / syntactic level.
Though there is no scala analogous type to C# or Java’s interfaces, traits are close. See here for more http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-5
Here you can see the treatment of the trait IEmployee’s Name property.
trait IEmployee {
protected var s : String = ""
def Name : String = s
def Name_=(news : String) = s = news
}class E extends IEmployee{
}class F extends IEmployee{
private var x = s
override def Name = x
override def Name_= (news : String) = { s = news; x = news; }
}
The property can be accessed via a DOT operator, e.g.
var f = new F
var e = new E
f.Name = “foo”
e.Name = “foo”
Alternatively IEmployee could have been written this way:
trait IEmployee {
var Name = ""
}class E extends IEmployee{
}
// However, this no longer compiles! [ I think this has larger implications (see below) ]
class F extends IEmployee{
private var x = ""
override def Name = x
override def Name_= (news : String) = x = news;
}
Omitting the override, results in an alternate error:
class F extends IEmployee{
private var x = ""
def Name = x
def Name_= (news : String) = x = news;}
Because the choice of using a var Name = “” [ field ] or a property def Name = … & def Name_= (news:String) = … [property] has affects what can be done in mixins, the UAP only applies access to but not overriding of a [field] / [property]
- In this case, the C# & Scala are similar, except that traits can have fields while interfaces can not.
Prefer flexibility
I am lead to believe that I should prefer:
> Using traits in method signatures: The corollary to “code to interfaces not concrete classes” in Scala becomes “code to traits not concrete classes”
> When defining traits, there is more flexibility in defining properties as opposed to fields.
In the wild, fields are preferred (but traits in signatures does hold)
That said, I have been told that fields are more often defined, "var Name = …” and can be changed later on, as needed, assuming you have access to the code.