Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Effective Dart Design Guidelines to Reflect Dart 3.0 Class Modifiers #6449

Merged
merged 18 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions examples/language/lib/patterns/json.dart

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see several changes in here related to JSON data. I suspect these are not part of the class modifiers PR. Can you update your PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The json changes are of another PR
but this PR doesn't contain any of those changes
this one is created on a separate branch
idk why its showing like that :/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the conflict warning has been taken care of :)
a false indentation in 'src/content/language/patterns.md' has been creating the problem
thank you

Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

void main() {
// #docregion json-1
var json = {
var data = {
'user': ['Lily', 13],
};
var {'user': [name, age]} = json;
var {'user': [name, age]} = data;
// #enddocregion json-1

{
// #docregion json-2
if (json is Map<String, Object?> &&
json.length == 1 &&
json.containsKey('user')) {
var user = json['user'];
if (data is Map<String, Object?> &&
data.length == 1 &&
data.containsKey('user')) {
var user = data['user'];
if (user is List<Object> &&
user.length == 2 &&
user[0] is String &&
Expand All @@ -27,7 +27,7 @@ void main() {
}
{
// #docregion json-3
if (json case {'user': [String name, int age]}) {
if (data case {'user': [String name, int age]}) {
print('User $name is $age years old.');
}
// #enddocregion json-3
Expand Down
2 changes: 1 addition & 1 deletion src/content/effective-dart/_toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ the project:
* <a href='/effective-dart/design#avoid-defining-a-one-member-abstract-class-when-a-simple-function-will-do'>AVOID defining a one-member abstract class when a simple function will do.</a>
* <a href='/effective-dart/design#avoid-defining-a-class-that-contains-only-static-members'>AVOID defining a class that contains only static members.</a>
* <a href='/effective-dart/design#avoid-extending-a-class-that-isnt-intended-to-be-subclassed'>AVOID extending a class that isn't intended to be subclassed.</a>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line shouldn't be removed AFAICT, can you make sure you re-ran the generator?

./dash_site effective-dart

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep my bad i thought that this section was removed from the design.md file that's why i remove the link too
lemme readd that
thanks for pointing it out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

* <a href='/effective-dart/design#do-document-if-your-class-supports-being-extended'>DO document if your class supports being extended.</a>
* <a href='/effective-dart/design#do-use-class-modifiers-to-control-if-your-class-can-be-extended'>DO use class modifiers to control if your class can be extended.</a>
* <a href='/effective-dart/design#avoid-implementing-a-class-that-isnt-intended-to-be-an-interface'>AVOID implementing a class that isn't intended to be an interface.</a>
* <a href='/effective-dart/design#do-document-if-your-class-supports-being-used-as-an-interface'>DO document if your class supports being used as an interface.</a>
* <a href='/effective-dart/design#prefer-defining-a-pure-mixin-or-pure-class-to-a-mixin-class'>PREFER defining a pure <code>mixin</code> or pure <code>class</code> to a <code>mixin class</code>.</a>
Expand Down
22 changes: 13 additions & 9 deletions src/content/effective-dart/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,13 @@ doesn't do that, it's best to assume you should *not* extend the class.
Otherwise, later changes to it may break your code.


### DO document if your class supports being extended

This is the corollary to the above rule. If you want to allow subclasses of your
class, state that. Suffix the class name with `Base`, or mention it in the
class's doc comment.
### DO use class modifiers to control if your class can be extended

Class modifiers like `final`, `interface`, or `sealed`
restrict how a class can be extended.
For example, use `final class A {}` or `interface class B {}` to prevent
extension outside the current library.
Use these modifiers to communicate your intent, rather than relying on documentation.

### AVOID implementing a class that isn't intended to be an interface

Expand All @@ -652,11 +653,14 @@ implicit interfaces except for classes that are clearly intended to be
implemented. Otherwise, you may introduce a coupling that the author doesn't
intend, and they may break your code without realizing it.

### DO document if your class supports being used as an interface

If your class can be used as an interface, mention that in the class's doc
comment.
### DO use class modifiers to control if your class can be an interface

When designing a library, use class modifiers like `final`, `base`, or `sealed` to enforce intended
usage. For example, use `final class C {}` or `base class D{}` to prevent
implementation outside the current library.
While it's ideal for all libraries to use these modifiers to enforce design intent,
developers may still encounter cases where they aren't applied. In such cases, be mindful of
unintended implementation issues.

<a id="do-use-mixin-to-define-a-mixin-type"></a>
<a id="avoid-mixing-in-a-class-that-isnt-intended-to-be-a-mixin"></a>
Expand Down
16 changes: 8 additions & 8 deletions src/content/language/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,14 @@ double calculateArea(Shape shape) => switch (shape) {
### Validating incoming JSON

[Map][] and [list][] patterns work well for destructuring key-value pairs in
JSON data:
deserialized data, such as data parsed from JSON:

<?code-excerpt "language/lib/patterns/json.dart (json-1)"?>
```dart
var json = {
var data = {
'user': ['Lily', 13],
};
var {'user': [name, age]} = json;
var {'user': [name, age]} = data;
```

If you know that the JSON data has the structure you expect,
Expand All @@ -379,10 +379,10 @@ Without patterns, validation is verbose:

<?code-excerpt "language/lib/patterns/json.dart (json-2)"?>
```dart
if (json is Map<String, Object?> &&
json.length == 1 &&
json.containsKey('user')) {
var user = json['user'];
if (data is Map<String, Object?> &&
data.length == 1 &&
data.containsKey('user')) {
var user = data['user'];
if (user is List<Object> &&
user.length == 2 &&
user[0] is String &&
Expand All @@ -402,7 +402,7 @@ method of validating JSON:

<?code-excerpt "language/lib/patterns/json.dart (json-3)"?>
```dart
if (json case {'user': [String name, int age]}) {
if (data case {'user': [String name, int age]}) {
print('User $name is $age years old.');
}
```
Expand Down