Skip to content

Commit 7252e02

Browse files
Merge pull request #17 from Workiva/rap-1500-manage-interface
RAP-1500 Extract manage methods into an interface
2 parents 6e1a83e + 977c975 commit 7252e02

File tree

1 file changed

+48
-7
lines changed

1 file changed

+48
-7
lines changed

lib/disposable.dart

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,28 @@ class _InternalDisposable implements _Disposable {
3737
}
3838
}
3939

40+
/// Managers for disposable members.
41+
///
42+
/// This interface allows consumers to exercise more control over how
43+
/// disposal is implemented for their classes.
44+
///
45+
/// When new management methods are to be added, they should be added
46+
/// here first, then implemented in [Disposable].
47+
abstract class DisposableManager {
48+
void manageDisposable(Disposable disposable);
49+
void manageDisposer(Disposer disposer);
50+
void manageStreamController(StreamController controller);
51+
void manageStreamSubscription(StreamSubscription subscription);
52+
}
53+
4054
/// A function that, when called, disposes of one or more objects.
4155
typedef Future<dynamic> Disposer();
4256

4357
/// Allows the creation of managed objects, including helpers for common patterns.
4458
///
45-
/// There are three ways to consume this class: as a mixin, a base class,
46-
/// and an interface. All should work fine but the first is the simplest
59+
/// There are four ways to consume this class: as a mixin, a base class,
60+
/// an interface, and a concrete class used as a proxy. All should work
61+
/// fine but the first is the simplest
4762
/// and most powerful. Using the class as an interface will require
4863
/// significant effort.
4964
///
@@ -102,7 +117,33 @@ typedef Future<dynamic> Disposer();
102117
/// myDisposable.didDispose.then((_) {
103118
/// // External cleanup
104119
/// });
105-
abstract class Disposable implements _Disposable {
120+
///
121+
/// Below is an example of using the class as a concrete proxy.
122+
///
123+
/// class MyLifecycleThing implements DisposableManager {
124+
/// Disposable _disposable = new Disposable();
125+
///
126+
/// MyLifecycleThing() {
127+
/// _disposable.manageStreamSubscription(someStream.listen(() => null));
128+
/// }
129+
///
130+
/// @override
131+
/// void manageStreamSubscription(StreamSubscription sub) {
132+
/// _disposable.manageStreamSubscription(sub);
133+
/// }
134+
///
135+
/// // ...more methods
136+
///
137+
/// Future<Null> unload() async {
138+
/// await _disposable.dispose();
139+
/// }
140+
/// }
141+
///
142+
/// In this case, we want `MyLifecycleThing` to have its own lifecycle
143+
/// without explicit reference to [Disposable]. To do this, we use
144+
/// composition to include the [Disposable] machinery without changing
145+
/// the public interface of our class or polluting its lifecycle.
146+
class Disposable implements _Disposable, DisposableManager {
106147
Completer<Null> _didDispose = new Completer<Null>();
107148
bool _isDisposing = false;
108149
List<_Disposable> _internalDisposables = [];
@@ -155,7 +196,7 @@ abstract class Disposable implements _Disposable {
155196
///
156197
/// The parameter may not be `null`.
157198
@mustCallSuper
158-
@protected
199+
@override
159200
void manageDisposable(Disposable disposable) {
160201
_throwIfNull(disposable, 'disposable');
161202
_internalDisposables.add(disposable);
@@ -165,7 +206,7 @@ abstract class Disposable implements _Disposable {
165206
///
166207
/// The parameter may not be `null`.
167208
@mustCallSuper
168-
@protected
209+
@override
169210
void manageDisposer(Disposer disposer) {
170211
_throwIfNull(disposer, 'disposer');
171212
_internalDisposables.add(new _InternalDisposable(disposer));
@@ -175,7 +216,7 @@ abstract class Disposable implements _Disposable {
175216
///
176217
/// The parameter may not be `null`.
177218
@mustCallSuper
178-
@protected
219+
@override
179220
void manageStreamController(StreamController controller) {
180221
_throwIfNull(controller, 'controller');
181222
_internalDisposables.add(new _InternalDisposable(() {
@@ -190,7 +231,7 @@ abstract class Disposable implements _Disposable {
190231
///
191232
/// The parameter may not be `null`.
192233
@mustCallSuper
193-
@protected
234+
@override
194235
void manageStreamSubscription(StreamSubscription subscription) {
195236
_throwIfNull(subscription, 'subscription');
196237
_internalDisposables

0 commit comments

Comments
 (0)