Construction Through Composition

In this construction, having access to the resource means having access to all of its capabilities, because the resource implements the capabilities directly as traits.

Before

object Before {

  final class Document(var name: String) {
    override def toString: String = s"Document($name)"
  }

  def main(args: Array[String]): Unit = {
    val document = new Document("will")
    document.name = "steve"
    println(s"Before: result = $document")
  }
}
Full source at GitHub

After

object AfterAttenuation {

  final class Document(private var name: String) extends Document.NameChanger {
    override def changeName(newName: String): Unit = {
      name = newName
    }
    override def toString: String = s"Document($name)"
  }

  object Document {
    trait NameChanger {
      def changeName(name: String): Unit
    }
  }

  def main(args: Array[String]): Unit = {
    val document = new Document("will")

    // expose a single facet through attenuation
    val nameChanger = new Document.NameChanger {
      override def changeName(name: String): Unit = document.changeName(name)
    }
    nameChanger.changeName("steve")
    println(s"AfterAttenuation: result = $document")
  }
}
Full source at GitHub