Files
100-exercises-to-learn-rust/book/src/03_ticket_v1/05_encapsulation.md
Luca Palmieri 96f06708b0 Render the book in PDF using pandoc and LaTeX. (#126)
* Render the book in PDF using `pandoc` and LaTeX.

* Fix installs.

* Go the apt-get route

* Another attempt

* Avoid installing twice.

* Re-order.

* Add more packages.

* Minimise deps. Fix link checker.

* Missing package.

* Missing package.

* Missing package.

* More packages.

* Missing package.

* Missing package.

* More packages...

* Remove.

* Fix link checker.

* Fix link checker.

* Fix path.

* Add subtitle.

* Avoid running over the right margin.

* Avoid running over the right margin.

* Formatting
2024-08-05 17:52:15 +02:00

2.3 KiB
Raw Blame History

Encapsulation

Now that we have a basic understanding of modules and visibility, lets circle back to encapsulation.
Encapsulation is the practice of hiding the internal representation of an object. It is most commonly used to enforce some invariants on the objects state.

Going back to our Ticket struct:

struct Ticket {
    title: String,
    description: String,
    status: String,
}

If all fields are made public, there is no encapsulation.
You must assume that the fields can be modified at any time, set to any value thats allowed by their type. You cant rule out that a ticket might have an empty title or a status that doesnt make sense.

To enforce stricter rules, we must keep the fields private1. We can then provide public methods to interact with a Ticket instance. Those public methods will have the responsibility of upholding our invariants (e.g. a title must not be empty).

If at least one field is private it is no longer possible to create a Ticket instance directly using the struct instantiation syntax:

// This won't work!
let ticket = Ticket {
    title: "Build a ticket system".into(),
    description: "A Kanban board".into(),
    status: "Open".into()
};

Youve seen this in action in the previous exercise on visibility.
We now need to provide one or more public constructors—i.e. static methods or functions that can be used from outside the module to create a new instance of the struct.
Luckily enough we already have one: Ticket::new, as implemented in a previous exercise.

Accessor methods

In summary:

  • All Ticket fields are private
  • We provide a public constructor, Ticket::new, that enforces our validation rules on creation

Thats a good start, but its not enough: apart from creating a Ticket, we also need to interact with it. But how can we access the fields if theyre private?

We need to provide accessor methods.
Accessor methods are public methods that allow you to read the value of a private field (or fields) of a struct.

Rust doesnt have a built-in way to generate accessor methods for you, like some other languages do. You have to write them yourself—theyre just regular methods.


  1. Or refine their type, a technique well explore later on.↩︎