Skip to content

Commit

Permalink
Update Effective Dart Design Guidelines to Reflect Dart 3.0 Class Mod…
Browse files Browse the repository at this point in the history
…ifiers (#6449)

This PR updates the Effective Dart Design Guidelines to align with Dart
3.0's introduction of class modifiers. The changes include:

For API Maintainers:

Removed the recommendation to document whether a class supports being
extended or used as an interface.

Added guidance to use class modifiers (e.g., final, sealed, interface,
mixin) to explicitly define a class's capabilities.

Emphasized that class modifiers should replace manual documentation for
enforcing restrictions on extending or implementing classes.

For Users:

Removed guidelines advising users to avoid extending or implementing
classes not meant for it, as these restrictions are now enforced by
class modifiers in Dart 3.0.

This change ensures the guidelines are up-to-date with Dart's latest
features and best practices.

Fixes: #6437
  • Loading branch information
MiniPiku authored Mar 5, 2025
1 parent 532a8e9 commit eb1ad75
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
4 changes: 2 additions & 2 deletions src/content/effective-dart/_toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ 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>
* <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#do-use-class-modifiers-to-control-if-your-class-can-be-an-interface'>DO use class modifiers to control if your class can be 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>

**Constructors**
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

0 comments on commit eb1ad75

Please sign in to comment.