Practical Refactoring Example
Refactoring procedural code into object-oriented programming (OOP) is a foundational skill for any Dart developer aiming to build maintainable and scalable applications. By moving from flat, function-based code to structured classes and interfaces, you can better organize logic, make code easier to extend, and reduce the risk of bugs as your project grows.
main.dart
12345678910111213141516171819202122232425262728293031// Procedural approach to managing shapes import 'dart:math'; // Calculate area for a circle double circleArea(double radius) { return pi * radius * radius; } // Calculate area for a rectangle double rectangleArea(double width, double height) { return width * height; } void printShapeArea(String shape, Map<String, double> params) { double area; if (shape == 'circle') { area = circleArea(params['radius']!); print('Circle area: $area'); } else if (shape == 'rectangle') { area = rectangleArea(params['width']!, params['height']!); print('Rectangle area: $area'); } else { print('Unknown shape'); } } void main() { printShapeArea('circle', {'radius': 5}); printShapeArea('rectangle', {'width': 4, 'height': 6}); }
In the procedural version, you manage shapes using separate functions and a control flow that checks shape types with strings. This approach leads to scattered logic, making it difficult to add new shapes or change existing behavior without editing multiple places in the code. The refactored OOP version introduces a Shape abstract class, which defines a common interface for all shapes. Both Circle and Rectangle inherit from Shape, implementing their own area methods. The printShapeArea function now accepts any Shape, supporting polymorphism and making it easy to add new shapes by simply extending the Shape class. This design centralizes logic, improves readability, and reduces the chance of errors when extending functionality.
main.dart
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// main.dart // Refactored OOP with interfaces for extensibility import 'dart:math'; // Interface for drawable objects abstract class Drawable { void draw(); } // Shape interface for polymorphism abstract class Shape { double area(); } // Circle implements both Shape and Drawable class Circle implements Shape, Drawable { final double radius; Circle(this.radius); @override double area() => pi * radius * radius; @override void draw() { print('Drawing a circle with radius $radius'); } } // Rectangle implements both Shape and Drawable class Rectangle implements Shape, Drawable { final double width; final double height; Rectangle(this.width, this.height); @override double area() => width * height; @override void draw() { print('Drawing a rectangle of $width x $height'); } } void printShapeArea(Shape shape) { print('${shape.runtimeType} area: ${shape.area()}'); } void drawShape(Drawable drawable) { drawable.draw(); } void main() { Shape circle = Circle(5); Shape rectangle = Rectangle(4, 6); printShapeArea(circle); printShapeArea(rectangle); drawShape(circle as Drawable); drawShape(rectangle as Drawable); }
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Can you show an example of the procedural and OOP versions side by side?
What are some best practices for refactoring procedural code to OOP in Dart?
How does using an abstract class improve code maintainability in this context?
Großartig!
Completion Rate verbessert auf 11.11
Practical Refactoring Example
Swipe um das Menü anzuzeigen
Refactoring procedural code into object-oriented programming (OOP) is a foundational skill for any Dart developer aiming to build maintainable and scalable applications. By moving from flat, function-based code to structured classes and interfaces, you can better organize logic, make code easier to extend, and reduce the risk of bugs as your project grows.
main.dart
12345678910111213141516171819202122232425262728293031// Procedural approach to managing shapes import 'dart:math'; // Calculate area for a circle double circleArea(double radius) { return pi * radius * radius; } // Calculate area for a rectangle double rectangleArea(double width, double height) { return width * height; } void printShapeArea(String shape, Map<String, double> params) { double area; if (shape == 'circle') { area = circleArea(params['radius']!); print('Circle area: $area'); } else if (shape == 'rectangle') { area = rectangleArea(params['width']!, params['height']!); print('Rectangle area: $area'); } else { print('Unknown shape'); } } void main() { printShapeArea('circle', {'radius': 5}); printShapeArea('rectangle', {'width': 4, 'height': 6}); }
In the procedural version, you manage shapes using separate functions and a control flow that checks shape types with strings. This approach leads to scattered logic, making it difficult to add new shapes or change existing behavior without editing multiple places in the code. The refactored OOP version introduces a Shape abstract class, which defines a common interface for all shapes. Both Circle and Rectangle inherit from Shape, implementing their own area methods. The printShapeArea function now accepts any Shape, supporting polymorphism and making it easy to add new shapes by simply extending the Shape class. This design centralizes logic, improves readability, and reduces the chance of errors when extending functionality.
main.dart
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162// main.dart // Refactored OOP with interfaces for extensibility import 'dart:math'; // Interface for drawable objects abstract class Drawable { void draw(); } // Shape interface for polymorphism abstract class Shape { double area(); } // Circle implements both Shape and Drawable class Circle implements Shape, Drawable { final double radius; Circle(this.radius); @override double area() => pi * radius * radius; @override void draw() { print('Drawing a circle with radius $radius'); } } // Rectangle implements both Shape and Drawable class Rectangle implements Shape, Drawable { final double width; final double height; Rectangle(this.width, this.height); @override double area() => width * height; @override void draw() { print('Drawing a rectangle of $width x $height'); } } void printShapeArea(Shape shape) { print('${shape.runtimeType} area: ${shape.area()}'); } void drawShape(Drawable drawable) { drawable.draw(); } void main() { Shape circle = Circle(5); Shape rectangle = Rectangle(4, 6); printShapeArea(circle); printShapeArea(rectangle); drawShape(circle as Drawable); drawShape(rectangle as Drawable); }
Danke für Ihr Feedback!