Last active
March 19, 2026 11:49
-
-
Save Falchio/c565f2ddec8da1748151e6e38b108d81 to your computer and use it in GitHub Desktop.
helper method is antipattern
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:flutter/material.dart'; | |
| void main() { | |
| runApp(const MyApp()); | |
| } | |
| class MyApp extends StatelessWidget { | |
| const MyApp({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| debugShowCheckedModeBanner: false, | |
| home: const DemoPage(), | |
| theme: ThemeData(useMaterial3: true), | |
| ); | |
| } | |
| } | |
| class DemoPage extends StatefulWidget { | |
| const DemoPage({super.key}); | |
| @override | |
| State<DemoPage> createState() => _DemoPageState(); | |
| } | |
| class _DemoPageState extends State<DemoPage> { | |
| int parentCounter = 0; | |
| @override | |
| Widget build(BuildContext context) { | |
| return Scaffold( | |
| appBar: AppBar( | |
| title: const Text('Helper method vs StatelessWidget'), | |
| ), | |
| body: ListView( | |
| padding: const EdgeInsets.all(16), | |
| children: [ | |
| Text( | |
| 'Parent rebuild counter: $parentCounter', | |
| style: Theme.of(context).textTheme.titleMedium, | |
| ), | |
| const SizedBox(height: 12), | |
| ElevatedButton( | |
| onPressed: () => setState(() => parentCounter++), | |
| child: const Text('Rebuild parent'), | |
| ), | |
| const SizedBox(height: 24), | |
| const Text( | |
| '1) Плохо: helper method возвращает Widget', | |
| style: TextStyle(fontWeight: FontWeight.bold), | |
| ), | |
| const SizedBox(height: 8), | |
| _buildBadCounter(), | |
| const SizedBox(height: 24), | |
| const Text( | |
| '2) Хорошо: отдельный StatelessWidget', | |
| style: TextStyle(fontWeight: FontWeight.bold), | |
| ), | |
| const SizedBox(height: 8), | |
| const GoodCounterCard(), | |
| ], | |
| ), | |
| ); | |
| } | |
| Widget _buildBadCounter() { | |
| debugPrint('build helper method: _buildBadCounter'); | |
| return Card( | |
| color: Colors.red.shade50, | |
| child: Padding( | |
| padding: const EdgeInsets.all(16), | |
| child: Column( | |
| crossAxisAlignment: CrossAxisAlignment.start, | |
| children: [ | |
| const Text('Этот блок строится через helper method'), | |
| const SizedBox(height: 8), | |
| const _BadCounterBody(), | |
| ], | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class _BadCounterBody extends StatefulWidget { | |
| const _BadCounterBody(); | |
| @override | |
| State<_BadCounterBody> createState() => _BadCounterBodyState(); | |
| } | |
| class _BadCounterBodyState extends State<_BadCounterBody> { | |
| int localCounter = 0; | |
| @override | |
| Widget build(BuildContext context) { | |
| debugPrint('build _BadCounterBody'); | |
| return Row( | |
| children: [ | |
| Text('Local counter: $localCounter'), | |
| const SizedBox(width: 12), | |
| ElevatedButton( | |
| onPressed: () => setState(() => localCounter++), | |
| child: const Text('+'), | |
| ), | |
| ], | |
| ); | |
| } | |
| } | |
| class GoodCounterCard extends StatelessWidget { | |
| const GoodCounterCard({super.key}); | |
| @override | |
| Widget build(BuildContext context) { | |
| debugPrint('build GoodCounterCard'); | |
| return Card( | |
| color: Colors.green.shade50, | |
| child: const Padding( | |
| padding: EdgeInsets.all(16), | |
| child: Column( | |
| crossAxisAlignment: CrossAxisAlignment.start, | |
| children: [ | |
| Text('Этот блок — отдельный StatelessWidget'), | |
| SizedBox(height: 8), | |
| _GoodCounterBody(), | |
| ], | |
| ), | |
| ), | |
| ); | |
| } | |
| } | |
| class _GoodCounterBody extends StatefulWidget { | |
| const _GoodCounterBody(); | |
| @override | |
| State<_GoodCounterBody> createState() => _GoodCounterBodyState(); | |
| } | |
| class _GoodCounterBodyState extends State<_GoodCounterBody> { | |
| int localCounter = 0; | |
| @override | |
| Widget build(BuildContext context) { | |
| debugPrint('build _GoodCounterBody'); | |
| return Row( | |
| children: [ | |
| Text('Local counter: $localCounter'), | |
| const SizedBox(width: 12), | |
| ElevatedButton( | |
| onPressed: () => setState(() => localCounter++), | |
| child: const Text('+'), | |
| ), | |
| ], | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment