From 8f29be148da2c1f128d0f6a346bfa381846826ac Mon Sep 17 00:00:00 2001 From: silverweed Date: Sun, 1 Oct 2017 15:05:02 +0200 Subject: [PATCH 1/2] Add Flyweight --- structural/flyweight.cr | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 structural/flyweight.cr diff --git a/structural/flyweight.cr b/structural/flyweight.cr new file mode 100644 index 0000000..08452a9 --- /dev/null +++ b/structural/flyweight.cr @@ -0,0 +1,68 @@ +# The flyweight pattern is a design pattern that is used to minimise +# resource usage when working with very large numbers of objects. +# When creating many thousands of identical objects, stateless flyweights +# can lower the memory used to a manageable level. + +alias Position = {Int32, Int32} + +# Contains the extrinsic actions that the object can do. +abstract class FlyweightTree + abstract def draw_at(pos : Position) +end + +# Implements the Flyweight interface, optionally keeping an extrinsic state +# which can be manipulated via that interface. +class Tree < FlyweightTree + property pos + + def initialize(species : String) + # Intrinsic (stateless) properties. These are shared between all instances of this tree. + @species = species + # Estrinsic (stateful) properties. These are accessed via the abstract interface + # provided by FlyweightTree + @pos = {0, 0} + end + + def draw_at(_pos : Position) + pos = _pos + puts "Drawing #{@species} at #{pos}" + end +end + +# Factory class for the flyweight objects. +class Forest + def initialize + @trees = {} of String => FlyweightTree + end + + def get_tree(species : String) + if @trees.has_key?(species) + return @trees[species] + else + tree = Tree.new(species) + @trees[species] = tree + return tree + end + end + + def tot_instances + @trees.size + end +end + +# Client code +forest = Forest.new +forest.get_tree("birch").draw_at({5, 6}) +forest.get_tree("acacia").draw_at({3, 1}) +forest.get_tree("magnolia").draw_at({15, 86}) +forest.get_tree("birch").draw_at({8, 15}) +forest.get_tree("acacia").draw_at({18, 4}) +forest.get_tree("baobab").draw_at({1, 41}) +forest.get_tree("magnolia").draw_at({80, 50}) +forest.get_tree("acacia").draw_at({22, 3}) +forest.get_tree("birch").draw_at({1, 42}) +forest.get_tree("baobab").draw_at({15, 7}) +forest.get_tree("acacia").draw_at({33, 49}) +forest.get_tree("magnolia").draw_at({0, 0}) +puts "-----------------------" +puts "Total instances created: #{forest.tot_instances}" From dda2ef5ab900657db738991791c5e44290183dfe Mon Sep 17 00:00:00 2001 From: Vitalii Elenhaupt Date: Mon, 2 Oct 2017 08:46:14 +0300 Subject: [PATCH 2/2] Add to Readme --- README.md | 1 + structural/flyweight.cr | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bf75b7a..5c6e069 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ The goal is to have a set of [GOF patterns](http://www.blackwasp.co.uk/gofpatter - [Composite](structural/composite.cr) - [Decorator](structural/decorator.cr) - [Facade](structural/facade.cr) + - [Flyweight](structural/flyweight.cr) ## Contribution diff --git a/structural/flyweight.cr b/structural/flyweight.cr index 08452a9..cd2fe99 100644 --- a/structural/flyweight.cr +++ b/structural/flyweight.cr @@ -37,11 +37,9 @@ class Forest def get_tree(species : String) if @trees.has_key?(species) - return @trees[species] + @trees[species] else - tree = Tree.new(species) - @trees[species] = tree - return tree + Tree.new(species).tap { |tree| @trees[species] = tree } end end @@ -66,3 +64,18 @@ forest.get_tree("acacia").draw_at({33, 49}) forest.get_tree("magnolia").draw_at({0, 0}) puts "-----------------------" puts "Total instances created: #{forest.tot_instances}" + +# Drawing birch at {5, 6} +# Drawing acacia at {3, 1} +# Drawing magnolia at {15, 86} +# Drawing birch at {8, 15} +# Drawing acacia at {18, 4} +# Drawing baobab at {1, 41} +# Drawing magnolia at {80, 50} +# Drawing acacia at {22, 3} +# Drawing birch at {1, 42} +# Drawing baobab at {15, 7} +# Drawing acacia at {33, 49} +# Drawing magnolia at {0, 0} +# ----------------------- +# Total instances created: 4