Created
July 24, 2024 05:28
-
-
Save amalChandran/34ab9f1adf80bb83476a0cc5710e4138 to your computer and use it in GitHub Desktop.
Solid Flutter - Open-Closed Principle Example
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'; | |
// Bad Example: Violating Open-Closed Principle | |
class BadButton extends StatelessWidget { | |
final String type; | |
final String label; | |
final VoidCallback onPressed; | |
BadButton({ | |
required this.type, | |
required this.label, | |
required this.onPressed, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
switch (type) { | |
case 'primary': | |
return ElevatedButton( | |
style: ElevatedButton.styleFrom(primary: Colors.blue), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
case 'secondary': | |
return OutlinedButton( | |
style: OutlinedButton.styleFrom(primary: Colors.blue), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
case 'danger': | |
return ElevatedButton( | |
style: ElevatedButton.styleFrom(primary: Colors.red), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
default: | |
return TextButton( | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} | |
} | |
// Good Example: Following Open-Closed Principle | |
abstract class ButtonStyle { | |
Widget build(String label, VoidCallback onPressed); | |
} | |
class PrimaryButtonStyle implements ButtonStyle { | |
@override | |
Widget build(String label, VoidCallback onPressed) { | |
return ElevatedButton( | |
style: ElevatedButton.styleFrom(primary: Colors.blue), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} | |
class SecondaryButtonStyle implements ButtonStyle { | |
@override | |
Widget build(String label, VoidCallback onPressed) { | |
return OutlinedButton( | |
style: OutlinedButton.styleFrom(primary: Colors.blue), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} | |
class DangerButtonStyle implements ButtonStyle { | |
@override | |
Widget build(String label, VoidCallback onPressed) { | |
return ElevatedButton( | |
style: ElevatedButton.styleFrom(primary: Colors.red), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} | |
class DefaultButtonStyle implements ButtonStyle { | |
@override | |
Widget build(String label, VoidCallback onPressed) { | |
return TextButton( | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} | |
class GoodButton extends StatelessWidget { | |
final ButtonStyle style; | |
final String label; | |
final VoidCallback onPressed; | |
GoodButton({ | |
required this.style, | |
required this.label, | |
required this.onPressed, | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return style.build(label, onPressed); | |
} | |
} | |
// Usage example | |
class MyWidget extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Column( | |
children: [ | |
GoodButton( | |
style: PrimaryButtonStyle(), | |
label: 'Primary Button', | |
onPressed: () {}, | |
), | |
GoodButton( | |
style: SecondaryButtonStyle(), | |
label: 'Secondary Button', | |
onPressed: () {}, | |
), | |
GoodButton( | |
style: DangerButtonStyle(), | |
label: 'Danger Button', | |
onPressed: () {}, | |
), | |
// Easy to extend with new button styles without modifying existing code | |
GoodButton( | |
style: CustomButtonStyle(), | |
label: 'Custom Button', | |
onPressed: () {}, | |
), | |
], | |
); | |
} | |
} | |
// Extending with a new button style without modifying existing code | |
class CustomButtonStyle implements ButtonStyle { | |
@override | |
Widget build(String label, VoidCallback onPressed) { | |
return ElevatedButton( | |
style: ElevatedButton.styleFrom( | |
primary: Colors.green, | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(18.0), | |
), | |
), | |
onPressed: onPressed, | |
child: Text(label), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment