Skip to content

Suggest to have only one public class per file using private classes for internal details. #59296

@Turskyi

Description

@Turskyi

I would like to suggest a new linter rule that checks if classes that are only used as internal implementation details in a file are declared as private. This can help to avoid exposing classes that are not meant to be used outside of the file and to follow the principle of encapsulation and information hiding.

For example, consider the following code snippet:

// dog.dart
class Dog {
  const Dog(this.name) : _dogSound = const _DogSound();
  final String name;
  final _DogSound _dogSound;

  void bark() {
    String sound = _dogSound.getSound();
    print("dog says: ${sound}");
  }
}

class _DogSound {
  const _DogSound() : sound = 'Woof!';

  final String sound;
// other fields

  String getSound() => sound;
// other methods
}

The class _DogSound is only used as an internal implementation of the class Dog, and it is not meant to be used outside of the file. Therefore, it is declared as private by adding an underscore prefix to its name. This way, it is clear that _DogSound is an implementation detail of Dog, and it cannot be imported or used by other files.

However, if we forget to make _DogSound private, and instead declare it as class DogSound, then it will be exposed outside of the file, and any developer would be able to use DogSound outside of the Dog, which may create issues since it was not designed to be used like this. For example, another file could import dog.dart and create a DogSound instance without a Dog and use it for a class Cat, or access and use other properties and methods, which could break the logic and consistency of the Dog class.

Therefore, the linter rule (for example prefer_private_classes) would suggest changing the declaration of class DogSound to class _DogSound.

This would help the developer to remember to make second, third and other classes inside one file private unless they are intended to be used outside of the file, in which case they should have their file.

I think this rule would be useful for Dart code quality and consistency, as it would enforce the Single Responsibility Principle (SRP) for classes and files.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3A lower priority bug or feature requestarea-devexpFor issues related to the analysis server, IDE support, linter, `dart fix`, and diagnostic messages.devexp-linterIssues with the analyzer's support for the linter packagelinter-lint-proposaltype-enhancementA request for a change that isn't a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions