Elly Fong-Jones | 4e3d25c7 | 2019-08-12 18:17:15 | [diff] [blame] | 1 | # The Passkey Pattern |
| 2 | |
Elly Fong-Jones | 0f5259c | 2019-08-13 14:39:21 | [diff] [blame] | 3 | For the Chromium implementation of this pattern, see |
| 4 | [//base/util/type_safety/pass_key.h]. |
| 5 | |
Elly Fong-Jones | 4e3d25c7 | 2019-08-12 18:17:15 | [diff] [blame] | 6 | The Passkey pattern is used when you need to expose a subset of a class's |
| 7 | methods to another class in a more granular way than simply friending the other |
| 8 | class. In essence, it involves creating a "passkey" class that can only be |
| 9 | constructed by specific other classes, and requiring an instance of that passkey |
| 10 | class to be passed in when calling methods you wish to restrict the use of. It |
| 11 | is used like this: |
| 12 | |
| 13 | ``` |
| 14 | class Foo { |
| 15 | public: |
| 16 | Foo(); |
| 17 | ~Foo(); |
| 18 | |
| 19 | void NormalPublicMethod(); |
| 20 | bool AnotherNormalPublicMethod(int a, int b); |
| 21 | |
| 22 | class BarPasskey { |
| 23 | private: |
| 24 | friend class Bar; |
| 25 | BarPasskey() = default; |
| 26 | ~BarPasskey() = default; |
| 27 | }; |
| 28 | |
| 29 | void HelpBarOut(BarPasskey, ...); |
| 30 | }; |
| 31 | |
| 32 | ... |
| 33 | |
| 34 | void Bar::DoStuff() { |
| 35 | foo->HelpBarOut(Foo::BarPasskey(), ...); |
| 36 | } |
| 37 | ``` |
| 38 | |
| 39 | The private constructor on `Foo::BarPasskey` prevents any class other than `Bar` |
| 40 | from constructing a `Foo::BarPasskey`, which means that: |
| 41 | |
| 42 | * Only `Bar` can call those methods |
| 43 | * `Bar` can delegate the ability to call those methods to other |
| 44 | classes/functions by passing them a `Foo::BarPasskey` instance |
| 45 | |
| 46 | This method is effectively free at runtime - a few extra bytes of argument space |
| 47 | are used to pass in the Passkey object. |
| 48 | |
| 49 | It is encouraged to leave the `BarPasskey` parameter unnamed to reinforce that it |
| 50 | carries no semantic information and is not actually used for anything. |
Elly Fong-Jones | 0f5259c | 2019-08-13 14:39:21 | [diff] [blame] | 51 | |
| 52 | [//base/util/type_safety/pass_key.h]: ../../base/util/type_safety/pass_key.h |