Flutterexperts

Crafting Next-Gen Apps with Flutter Power
FlyWeight Design Pattern In Flutter

The Flyweight design is tied in with utilizing memory proficiently. If your Dart or Flutter application manages moderately overwhelming items, and it needs to launch a large number of them, using this pattern can help spare memory and increment execution by staying away from information duplication. Articles that have the same information can share that information as opposed to replicating it wherever it’s required.

In this article, we will explore the Flyweight Design Pattern in a flutter. We will implement a demo flyweight design pattern in your flutter applications.

Table of Contents:

Design Pattern

Structural Design Patterns

Flyweight Design Pattern

Applicable

Code Implementation

Code File

Conclusion



Design Pattern

Design Pattern could be characterized as a typical repeatable answer for repeating issues in programming design. Design patterns can not be identified with a completed design that will be legitimately utilized in code; however, it could be comprehended as a portrayal or layout for how to tackle any normal issue that may happen as a rule.

So If we experience this Definition we will find that

  • It is an answer to repeating issues of programming development.
  • It’s anything but an example code that will be legitimately utilized in the task.
  • It is only a layout that assists with taking care of any difficulty that happens in programming development.

Structural Design Patterns

Structural patterns assist us with molding the connections between the objects and classes we make. These patterns are centered around how classes acquire from one another, how items can be made out of different objects, and how objects and classes interrelate. In these articles, you’ll figure out how to manufacture enormous, complete frameworks from easier, singular modules and parts. The pattern helps us in making adaptable, inexactly coupled, interconnecting code modules to finish complex undertakings in a reasonable manner.

  • Flyweight:- It contains an inherent state while the extrinsic state is passed to the Flyweight’s strategies. The object should be shareable.
  • FlyweightFactory:- It creates and oversees flyweight objects. At the point when a customer calls the factory, it checks whether the particular flyweight object exists. In the event that indeed, it is basically come back to the customer, in any case, another example of the flyweight object is made and afterward returned.
  • Context:- It contains the extrinsic state, special over every single unique item.
  • Client:- It computes or stores the outward condition of Flyweight (s) and keeps up a reference to it/them.

Flyweight Design Pattern

Flyweight has a place with the classification of structural design patterns. Utilize sharing to help huge quantities of fine-grained protests productively.

To spare space, you can isolate the natural state into a flyweight object, making just one duplicate of every one of a kind sort and reserving it for reuse. The extrinsic state goes in its own object, alongside a reference to the natural express the item needs. Rather than putting away similar information in various objects, you can store inherent information in only a couple of flyweight protests that are connected to suitable setting objects, where extrinsic information is kept.

Applicable

The Flyweight design pattern ought to be utilized just when your program must help a colossal number of items which scarcely fit into accessible RAM. The example’s adequacy relies upon how and where it’s utilized. It would be the most valuable when:

  • An application utilizes countless objects.
  • The object channel all accessible RAM on an objective device.
  • The items contain copy states which can be separated and shared between various objects.
  • Numerous gatherings of objects could be supplanted by a couple of shared items once the extrinsic state is expelled;
  • The application doesn’t rely upon object personality. Since flyweight objects are shared, adroitly particular items could be considered as a similar object.

Code Implementation

Shape Type

It is a enumerator class defining possible shape types was Circle and Square.

Circle and Square are concrete situated shape classes that actualize the abstract class PositionedShape. Both of these shapes have their own intrinsic state: circle characterizes shading and diameter across properties while square contains shading, width properties, and getter tallness, which restores a similar incentive as width.

enum ShapeType {
Circle,
Square,
}

Circle Shape

It is a particular usage of the PositionedShape interface speaking to the shape of a circle.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/positioned_shape.dart';

class CircleShape implements PositionedShape {
final Color color;
final double diameter;

circleShape({
@required this.color,
@required this.diameter,
}) : assert(color != null),
assert(diameter != null);

@override
Widget render(double x, double y) {
return Positioned(
left: x,
bottom: y,
child: Container(
height: diameter,
width: diameter,
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
);
}
}

Square Shape

It is a particular usage of the PositionedShape interface speaking to the shape of a square

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/positioned_shape.dart';

class SquareShape implements PositionedShape {
final Color color;
final double width;

SquareShape({
@required this.color,
@required this.width,
}) : assert(color != null),
assert(width != null);

double get height => width;

@override
Widget render(double x, double y) {
return Positioned(
left: x,
bottom: y,
child: Container(
height: height,
width: width,
color: color,
),
);
}
}

Positioned Shape

It defines the render() method to be implemented by shape classes.

import 'package:flutter/widgets.dart';

abstract class PositionedShape {
Widget render(double x, double y);
}

Create a new dart file called category_page.dart inside the lib folder.

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_flyweight_design_demo/constants.dart';
import 'package:flutter_flyweight_design_demo/repo/modal/design_pattern_category_modal.dart';
import 'package:flutter_flyweight_design_demo/screens/category/category_card.dart';
import 'package:flutter_flyweight_design_demo/utils/custom/custom_back_button.dart';
import 'package:flutter_flyweight_design_demo/utils/fade_transition.dart';


class CategoryPage extends StatefulWidget {
final DesignPatternCategory category;

const CategoryPage({
@required this.category,
Key key,
}) : assert(category != null),
super(key: key);

@override
_CategoryPageState createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage>
with SingleTickerProviderStateMixin {
final double _listAnimationIntervalStart = 0.65;
final double _preferredAppBarHeight = 56.0;

AnimationController _fadeSlideAnimationController;
ScrollController _scrollController;
double _appBarElevation = 0.0;
double _appBarTitleOpacity = 0.0;
@override
void initState() {
super.initState();
_fadeSlideAnimationController = AnimationController(
duration: Duration(milliseconds: 1500),
vsync: this,
)..forward();

_scrollController = ScrollController()
..addListener(() {
setState(() {
_appBarElevation =
_scrollController.offset > _scrollController.initialScrollOffset
? 4.0
: 0.0;
_appBarTitleOpacity = _scrollController.offset >
_scrollController.initialScrollOffset +
_preferredAppBarHeight / 2
? 1.0
: 0.0;
});
});
}

@override
void dispose() {
_fadeSlideAnimationController.dispose();
_scrollController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Hero(
tag: "${widget.category.id}",
child: Container(
color: Color(widget.category.color),
),
),
SafeArea(
child: Column(
children: <Widget>[
FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.5),
end: Offset(0.0, 0.0),
),
begin: 0.0,
end: _listAnimationIntervalStart,
child: PreferredSize(
preferredSize: Size.fromHeight(_preferredAppBarHeight),
child: AppBar(
title: AnimatedOpacity(
opacity: _appBarTitleOpacity,
duration: const Duration(milliseconds: 250),
child: Text(widget.category.title),
),
backgroundColor: Color(widget.category.color),
elevation: _appBarElevation,
leading: CustomBackButton(
color: Colors.white,
),
),
),
),
Expanded(
child: ScrollConfiguration(
behavior: ScrollBehavior(),
child: SingleChildScrollView(
controller: _scrollController,
padding: const EdgeInsets.fromLTRB(
paddingL,
paddingZero,
paddingL,
paddingL,
),
child: Column(
children: <Widget>[
FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.5),
end: Offset(0.0, 0.0),
),
begin: 0.0,
end: _listAnimationIntervalStart,
child: Row(
children: <Widget>[
Text(
widget.category.title,
style: Theme.of(context)
.textTheme
.headline6
.copyWith(
fontSize: 32.0,
color: Colors.white,
),
),
],
),
),
const SizedBox(height: spaceL),
for (var i = 0;
i < widget.category.patterns.length;
i++)
FadeTransitionScreen.staggered(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.1),
end: Offset(0.0, 0.0),
),
singleItemDurationInterval: 0.05,
index: i,
begin: _listAnimationIntervalStart,
end: 1.0,
child: Container(
margin: const EdgeInsets.only(top: marginL),
child: CategoryCard(
designPattern: widget.category.patterns[i],
),
),
),
],
),
),
),
),
],
),
),
],
),
);
}
}

In this screen, a title and card have shown with description. The description comes to the JSON file.

Shape Data

A data class which defines the create shape() method to create a shape by providing its type.

import 'package:flutter/material.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/positioned_shape.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/shape_type.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/shapes/circle_shape.dart';
import 'package:flutter_flyweight_design_demo/flyweight_patterns/shapes/square_shape.dart';
class ShapeData {
PositionedShape createShape(ShapeType shapeType) {
switch (shapeType) {
case ShapeType.Circle:
return CircleShape(
color: Colors.red.withOpacity(0.2),
diameter: 10.0,
);
case ShapeType.Square:
return SquareShape(
color: Colors.blue.withOpacity(0.2),
width: 10.0,
);
default:
throw new Exception("Shape type '$shapeType' is not supported.");
}
}
}

Create a new dart file called design_pattern_page.dart inside the lib folder.

Scaffold(
bottomNavigationBar: FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 1.0),
end: Offset(0.0, 0.0),
),
begin: _contentAnimationIntervalStart,
end: 1.0,
child: BottomNavigationBar(
currentIndex: _tabController.index,
backgroundColor: Colors.pink[200],
elevation: _bottomNavigationBarElevation,
selectedIconTheme: IconThemeData(size: 20.0),
selectedItemColor: Colors.black,
unselectedIconTheme: IconThemeData(size: 20.0),
unselectedItemColor: Colors.black45,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
title: Text('Data'),
icon: Icon(FontAwesomeIcons.file,color: Colors.greenAccent,),
),
BottomNavigationBarItem(
title: Text('Demo'),
icon: Icon(FontAwesomeIcons.solidLightbulb,color: Colors.greenAccent,),
),
],
onTap: onBottomNavigationBarItemTap,
),
),
body: Stack(
children: <Widget>[
Hero(
tag: "${widget.designPattern.id}",
child: Container(
color: Colors.pink[200],
),
),
SafeArea(
child: Column(
children: <Widget>[
FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.5),
end: Offset(0.0, 0.0),
),
begin: 0.0,
end: _contentAnimationIntervalStart,
child: PreferredSize(
preferredSize: Size.fromHeight(_preferredAppBarHeight),
child: AppBar(
title: AnimatedOpacity(
opacity: _appBarTitleOpacity,
duration: const Duration(milliseconds: 250),
child: Text(
widget.designPattern.title,
style: TextStyle(
color: Colors.black,
),
),
),
backgroundColor: Colors.pink[200],
elevation: _appBarElevation,
leading: CustomBackButton(
color: Colors.black,
),
),
),
),
Expanded(
child: TabBarView(
controller: _tabController,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ScrollConfiguration(
behavior: ScrollBehavior(),
child: SingleChildScrollView(
controller: _scrollController,
padding: const EdgeInsets.fromLTRB(
paddingL,
paddingZero,
paddingL,
paddingL,
),
child: Column(
children: <Widget>[
FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.25),
end: Offset(0.0, 0.0),
),
begin: 0.0,
end: _contentAnimationIntervalStart,
child: DesignPatternHeader(
designPattern: widget.designPattern,
),
),
const SizedBox(height: spaceL),
FadeTransitionScreen(
controller: _fadeSlideAnimationController,
slideAnimationTween: Tween<Offset>(
begin: Offset(0.0, 0.01),
end: Offset(0.0, 0.0),
),
begin: _contentAnimationIntervalStart,
end: 1.0,
child: FutureBuilder(
future:
repository.get(widget.designPattern.id),
initialData: "",
builder: (_, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return MarkdownBody(
data: snapshot.data,
);
}
                                return CircularProgressIndicator(
backgroundColor: lightBackgroundColor,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.black.withOpacity(0.65),
),
);
},
),
),
],
),
),
),
widget.example,
],
),
),
],
),
),
],
),
);

In this screen, we will add a tab bar with heading and icons, and add dummy data on this page.

Flyweight Page

Create a new dart file called flyweight_page.dart inside the lib folder.

Stack(
children: <Widget>[
for (var shape in _shapesList)
PositionedShapePage(
shape: shape,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SwitchListTile.adaptive(
title: Text(
'Flyweight Data',
style: TextStyle(color: Colors.black,fontSize: 25,
fontWeight: FontWeight.bold,
),
),
activeColor: Colors.black,
value: _useFlyweightFactory,
onChanged: _toggleUseFlyweightFactory,
),
],
),
Center(
child: Text(
'Shape count: $_shapeInstancesCount',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
);

In this screen, we will add a toggle button and shown shape count on this screen. On this screen, you will see the background circle and square shape with small different colors.

Code File

https://gist.github.com/ShaiqAhmedkhan/6687d8d03c2964bb96c5e79a1f93e89a#file-design_pattern_details-dart

You will see a full code on a GitHub, and this is a small demo implement on a flyweight design pattern, and the below video shows how Flyweight will work.

Conclusion

In the article, I have explained the basic structure of Flyweight, you can modify this code according to your choice, and this was a small introduction of the Flyweight Design Pattern in Flutter from my side .

I hope this blog will provide you with sufficient information in Trying up Flyweight in your flutter projects. This is a demo program that will implement Flyweight design patterns in a flutter, So please try it.

❤ ❤ Thanks for reading this article ❤❤


If I got something wrong? Let me know in the comments. I would love to improve.

Clap 👏 If this article helps you.

find the source code of the Flutter Flyweight Design Demo:

flutter-devs/flutter_flyweight_design_demo
A new Flutter application. This project is a starting point for a Flutter application. A few resources to get you…github.com


Feel free to connect with us:
And read more articles from FlutterDevs.com.

FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! You can connect with us on FacebookGitHubTwitter, and LinkedIn for any flutter-related queries.

We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.


Leave comment

Your email address will not be published. Required fields are marked with *.