Last active
September 20, 2024 16:58
-
-
Save misterfourtytwo/bd604e5f6cf73bb42d7b1e1c8f562bea to your computer and use it in GitHub Desktop.
Decompose different user subfeatures into mixins with freezed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:freezed_annotation/freezed_annotation.dart'; | |
part 'user.freezed.dart'; | |
abstract class IUserBase { | |
int? get id; | |
} | |
enum UserStatus { | |
normal, | |
pro, | |
banned, | |
} | |
abstract class IUserStatus { | |
UserStatus get status; | |
} | |
extension ProExtension on IUserBase { | |
bool get isPro => this is IUserStatus && | |
(this as IUserStatus).status == UserStatus.pro; | |
} | |
mixin ProMixin implements IUserStatus { | |
bool get isPro => status == UserStatus.pro; | |
} | |
@freezed | |
class UserBase with _$UserBase implements IUserBase { | |
const factory UserBase({ | |
required int? id, | |
}) = _UserBase; | |
} | |
@freezed | |
class User with _$User implements IUserBase, IUserStatus { | |
@With<ProMixin>() | |
const factory User({ | |
required int? id, | |
required UserStatus status, | |
}) = _User; | |
} | |
void main() { | |
/// Suppose we have a widespread widget depending on user subclass, | |
/// which can implement different interfaces, based on those we might want to | |
/// show userStatus badge. | |
/// Then we might write something like this: | |
/// ```dart | |
/// Widget build(BuildContext context) { | |
/// return Column( | |
/// children: [ | |
/// // ... | |
/// if (x is IUserStatus) StatusBadge(isPro: x.isPro), | |
/// // ... | |
/// ], | |
/// ); | |
/// } | |
/// ``` | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment