← Назад к вопросам

По каким правилам в Dart именуются методы?

1.0 Junior🔥 121 комментариев
#Dart#ООП и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

По каким правилам в Dart именуются методы?

В Dart существуют строгие соглашения по именованию (naming conventions), которые определены в официальном Dart style guide. Это не только вопрос стиля — эти правила помогают другим разработчикам понять назначение метода.

1. Основное правило: camelCase

Все методы в Dart именуются в camelCase (первое слово со строчной буквы, остальные с заглавной).

// ✅ Правильно
void calculateTotal() {}
String getName() {}
bool isValidEmail(String email) {}
Future<void> fetchUserData() {}
void onButtonPressed() {}

// ❌ Неправильно
void calculatetotal() {}       // Не camelCase
void CalculateTotal() {}       // PascalCase (для классов)
void calculate_total() {}      // snake_case
void CALCULATE_TOTAL() {}      // SCREAMING_SNAKE_CASE

2. Глаголы в начале

Методы обычно начинаются с глагола, который описывает действие.

// ✅ Начинаются с глагола (действия)
void calculate() {}
void validate() {}
void initialize() {}
void dispose() {}
List<User> getUsers() {}
String formatDate(DateTime date) {}
void saveData() {}
Future<void> uploadImage() {}
void removeItem(int index) {}
void toggleTheme() {}

// ❌ Неправильно — не ясно, что это метод
void users() {}        // Выглядит как свойство, не метод
void data() {}         // Неясно, что делает
void response() {}     # Неясно, действие это или свойство

3. Логические методы (возвращают bool)

Методы, возвращающие логическое значение, обычно начинаются с:

  • is — состояние
  • has — наличие
  • can — возможность
  • should — должно ли
  • would — условие
// ✅ Правильные имена для методов, возвращающих bool
bool isEmpty() {}              // is + прилагательное
bool isValid() {}
bool isLoggedIn() {}
bool isLoading() {}

bool hasError() {}             // has + существительное
bool hasPermission() {}
bool hasInternet() {}

bool canDelete() {}            // can + глагол
bool canEdit() {}
bool canDownload() {}

bool shouldRetry() {}          // should + глагол
bool shouldRefresh() {}

bool wouldCauseError() {}      # would + глагол

// ❌ Неправильно
bool validate() {}             # Неясно, true = valid или invalid?
bool checkEmail() {}           # Неясно, что возвращает
bool user() {}                 # Очень неясно

4. Методы для getter/setter

В Dart есть специальный синтаксис для свойств, но иногда нужны методы.

// ✅ Свойства (если просто чтение)
class User {
  final String name;  // Свойство
  int get age => _birthYear == null ? 0 : DateTime.now().year - _birthYear!;
  
  // Setter
  set age(int value) => _birthYear = DateTime.now().year - value;
}

// ✅ Методы (если требует логики)
class User {
  String? _name;
  
  String getName() => _name ?? 'Unknown';
  void setName(String value) => _name = value;
  
  // Или используй свойства с логикой
  String get name => _name ?? 'Unknown';
  set name(String value) => _name = value;
}

// ❌ Неправильные имена
void setUserName() {}          # Не используй set в обычных методах
String getUserName() {}        # Лучше использовать get свойство

5. Асинхронные методы (Future/Stream)

Обычно именуются как обычные методы, но часто с глаголом действия.

// ✅ Правильные имена для async методов
Future<List<User>> fetchUsers() {}
Future<void> saveData() {}
Future<String> downloadFile(String url) {}
Stream<int> countdownTimer() {}
Future<User?> getUserById(int id) {}

// ❌ Неправильно
Future<List<User>> users() {}     # Неясно, что это async
Future<void> getUsersFromAPI() {}  # Лишнее слово

6. Callback методы (listeners, handlers)

Обычно начинаются с on + действие.

// ✅ Правильные имена для callback'ов
void onPressed() {}
void onChanged(String value) {}
void onError(Exception error) {}
void onSuccess(User user) {}
void onItemTapped(int index) {}
void onDrawerClosed() {}
void onScrollEnd() {}
void onDataReceived(List<T> data) {}

// ❌ Неправильно
void handlePressed() {}        # Используй "on" для callbacks
void pressedCallback() {}      # Неинформативно
void _pressed() {}             # Неясно, что это callback

7. Приватные методы (начинаются с _)

// ✅ Приватные методы также следуют camelCase
class User {
  String _name = '';
  
  // Приватный метод
  void _validateEmail(String email) {}
  String _formatName() => _name.trim();
  bool _hasSpecialCharacters(String text) {}
  
  // Публичный метод может вызывать приватный
  void setEmail(String email) {
    if (_validateEmail(email)) {
      this._email = email;
    }
  }
}

// ❌ Неправильно
void __doubleUnderscore() {}   # Не используй двойное подчёркивание
void _PRIVATE_METHOD() {}      # Не используй SCREAMING_SNAKE_CASE

8. Фабричные методы (factory constructors)

Обычно именуются с глаголом (fromJSON, parse и т.д.).

// ✅ Правильные имена для factory методов
class User {
  final String name;
  
  User(this.name);
  
  // Factory methods
  factory User.fromJson(Map<String, dynamic> json) {
    return User(json['name'] as String);
  }
  
  factory User.empty() {
    return User('');
  }
  
  factory User.fromString(String nameAndAge) {
    final parts = nameAndAge.split(':');
    return User(parts[0]);
  }
}

// Использование
final user1 = User.fromJson({'name': 'John'});
final user2 = User.empty();
final user3 = User.fromString('John:30');

9. Методы преобразования

Для преобразования из одного типа в другой используется to + тип.

// ✅ Правильные имена для методов преобразования
class User {
  String toJson() => jsonEncode({'name': name});
  Map<String, dynamic> toMap() => {'name': name};
  String toString() => 'User($name)';
  String toFormattedString() => 'Name: $name';
  int toHashCode() => name.hashCode;
}

class DateTime {
  String toIso8601String() {}   # Преобразование в ISO строку
  int toMillisecondsSinceEpoch() {}  # Преобразование в число
}

// Использование
final user = User('John');
print(user.toString());       // User(John)
print(user.toJson());         // {"name":"John"}

10. Операторы (operators)

В Dart можно переопределять операторы, и они имеют особые имена.

// ✅ Правильные имена операторов
class Vector {
  int x, y;
  
  Vector(this.x, this.y);
  
  // Арифметические операторы
  Vector operator +(Vector other) => Vector(x + other.x, y + other.y);
  Vector operator -(Vector other) => Vector(x - other.x, y - other.y);
  Vector operator *(int scalar) => Vector(x * scalar, y * scalar);
  Vector operator /(int scalar) => Vector(x ~/ scalar, y ~/ scalar);
  
  // Операторы сравнения
  bool operator ==(Object other) {
    if (other is! Vector) return false;
    return x == other.x && y == other.y;
  }
  
  int get hashCode => x.hashCode ^ y.hashCode;
  
  // Операторы индексирования
  int operator [](int index) => index == 0 ? x : y;
  void operator []=(int index, int value) {
    if (index == 0) x = value;
    else y = value;
  }
}

// Использование
final v1 = Vector(1, 2);
final v2 = Vector(3, 4);
final v3 = v1 + v2;  // Vector(4, 6)
final v4 = v1 * 2;   // Vector(2, 4)

11. Методы инициализации и очистки

Уточнённые имена для жизненного цикла.

// ✅ Правильные имена для lifecycle методов
abstract class BaseService {
  Future<void> initialize() {}      // Инициализация
  Future<void> dispose() {}          // Очистка
  void reset() {}                    # Сброс состояния
  void clear() {}                    # Очистка данных
  void reload() {}                   # Перезагрузка
}

// В StatefulWidget
class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  void initState() {}       // Инициализация (обязательно)
  
  @override
  void didUpdateWidget(MyWidget oldWidget) {}  // Обновление
  
  @override
  void deactivate() {}      # Деактивация
  
  @override
  void dispose() {}         # Удаление (обязательно)
}

12. Тестовые методы

В тестах немного другие соглашения.

// ✅ Правильные имена для test методов
void main() {
  test('should return user when id is valid', () {
    // Arrange
    // Act
    // Assert
  });
  
  test('throws exception when email is invalid', () {
    // Test
  });
  
  testWidgets('displays loading spinner while fetching', (WidgetTester tester) {
    // Test
  });
  
  group('User repository', () {
    test('returns list of users', () {});
    test('caches results', () {});
  });
}

Сводная таблица: Правила именования

Тип методаШаблонПримерВозврат
Обычныйглагол + существительноеcalculateTotal()Любой
Booleanis/has/can/should + прилагательноеisEmpty(), hasError()bool
Callbackon + действиеonPressed(), onChange()void/Future
Asyncглагол + существительноеfetchUsers(), saveData()Future
Преобразованиеto + типtoString(), toJson()Тип
Factoryfrom + источникfromJson(), fromString()Объект класса
Приватный_ + обычные правила_validateEmail()Любой
Операторoperator + символoperator +()Зависит

Linter правила для Dart

Дартовый linter (в pubspec.yaml) проверяет эти правила:

linter:
  rules:
    - camel_case_extensions      # Расширения в camelCase
    - camel_case_types           # Типы в PascalCase
    - library_names              # Библиотеки в snake_case
    - library_prefixes           # Префиксы в snake_case
    - non_constant_identifier_names  # Переменные в camelCase

Best Practice пример

// ✅ Полный пример правильного именования
abstract class UserRepository {
  Future<List<User>> getUsers();  # Fetch plural
  Future<User?> getUserById(int id);  # Fetch singular
  Future<void> saveUser(User user);   # Action
  Future<void> deleteUser(int id);    # Action
  Stream<User> watchUser(int id);     # Observe changes
}

class UserRepositoryImpl implements UserRepository {
  final _api = ApiClient();
  final _cache = <int, User>{};
  
  @override
  Future<List<User>> getUsers() async {
    try {
      return await _fetchFromAPI();  # Private helper
    } catch (e) {
      return _getCachedUsers();      # Private helper
    }
  }
  
  @override
  Future<User?> getUserById(int id) async {
    if (_isCached(id)) return _cache[id];  # Private check
    return await _api.getUser(id);
  }
  
  @override
  Future<void> saveUser(User user) => _api.saveUser(user);
  
  @override
  Future<void> deleteUser(int id) => _api.deleteUser(id);
  
  @override
  Stream<User> watchUser(int id) => _api.watchUser(id);
  
  // Private methods
  Future<List<User>> _fetchFromAPI() => _api.getUsers();
  List<User> _getCachedUsers() => _cache.values.toList();
  bool _isCached(int id) => _cache.containsKey(id);
}

Резюме

Правила именования методов в Dart:

  1. camelCase — первое слово со строчной буквы
  2. Глагол в начале — описывает действие
  3. Boolean методы — is/has/can/should + прилагательное
  4. Callback методы — on + действие
  5. Async методы — обычное имя (Future показывает асинхронность)
  6. Преобразование — to + тип
  7. Factory методы — from + источник
  8. Приватные методы — _ + обычные правила
  9. Операторы — operator + символ

Главное правило: Имя метода должно чётко описывать, что он делает. Если не ясно из названия — переименуй!