Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Flyweight #6

Merged
merged 3 commits into from Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -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

Expand Down
81 changes: 81 additions & 0 deletions structural/flyweight.cr
@@ -0,0 +1,81 @@
# 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)
@trees[species]
else
Tree.new(species).tap { |tree| @trees[species] = 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}"

# 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