Encapsulate Field
Before you begin: Fields, properties, getters, and setters.
Encapsulate Field replaces direct access to stored data with an explicit access API, usually a property or getter and setter. This gives the owner a place to control access while callers depend less directly on the storage representation. 1
Original version: callers read and write storage directly
public sealed class Player
{
public int Score;
}A caller assigns player.Score = 12. Score is a public field; reads and writes go directly to that field.
class Player:
def __init__(self):
self.score = 0The instance attribute is public. Any caller can assign a new score without passing through player-owned logic.
Refactored version: put an accessor in the path
public sealed class Player
{
private int score;
public int Score
{
get { return score; }
set { score = value; }
}
}The ordinary call still looks like player.Score = 12, but it now uses the property’s setter. The expanded declaration makes the backing field visible; an auto-property is also suitable when no custom accessor behavior is needed.
class Player:
def __init__(self):
self._score = 0
@property
def score(self):
return self._score
@score.setter
def score(self, value):
self._score = valueA caller still writes player.score = 12. The property now routes that assignment through the setter. _score is the backing attribute, internal by convention.
Accessors are an opportunity, not an automatic guarantee
These setters intentionally accept exactly what the old fields accepted. They do not reject negative scores, send notifications, or add synchronization. Those could be useful changes, but each alters behavior and needs its own tests and explanation.
Nor is this complete information hiding: the public API still exposes a freely writable score. An operation such as AwardPoints might better express the permitted action, but that is a further design decision.
For a public C# library, replacing a field with a property can break binary compatibility, reflection, and ref uses even if ordinary source assignments look unchanged. Inspect those consumers before publishing the change.
Use encapsulation to establish meaningful control or prepare a representation change. Do not assume a trivial getter and setter have made arbitrary mutation safe merely because the backing field is private.
Sources
- Martin Fowler — Encapsulate Variable, the broader refactoring that includes Encapsulate Field.
- Microsoft — Properties and Python — property, for the accessor mechanisms.