Share This Article
The policy pattern in Ruby is a widely used software design pattern that allows you to encapsulate different behavior in separate classes, aka policies.
In general, you would use this pattern when you have a different behavior that needs to be applied in different circumstances.
For example, you may want to apply a discount to an order, but there are different rules for calculating the discount. In this case, you could create a separate class for each discount rule and apply the one appropriate for the current order.
Here’s how you would implement this in ruby:
class Order
def initialize(items, discount_policy)
@items = items
@discount_policy = discount_policy
end
def total
@items.sum(&:price) - @discount_policy.calculate(self)
end
end
class NoDiscount
def calculate(order)
0
end
end
class PercentageDiscount
def initialize(percentage)
@percentage = percentage
end
def calculate(order)
order.total * @percentage/100
end
end
class FixedDiscount
def initialize(amount)
@amount = amount
end
def calculate(order)
[@amount, order.total].min
end
end
order = Order.new([{price: 100}, {price: 200}], PercentageDiscount.new(10))
order.total
# 270
In this example, we have an Order class that takes a list of items and a discount policy.
We have three different discount policies:
– NoDiscount
– PercentageDiscount
– FixedDiscount
The total
method of the Order class will first sum the prices of all items in the order and then apply the discount from the chosen policy.
This is a simple example, but you could imagine a more complicated system where you have different policies for different types of items, different policies for different customer groups, or whatever you can think of.
The important thing is that you can apply the same behavior (calculating the discount) differently by using different policies.
When to Use the Policy Pattern
The policy pattern is very flexible and can be used in many different situations.
But in general, you want to use this pattern when you have a different behavior that needs to be applied in different circumstances, and you want that behavior to be encapsulated in separate classes.
With the policy pattern, it’s easy to add or remove policies as needed, and you can also unit-test the policies separately from the main application logic.
Summary
In this article, you’ve learned about the policy pattern and how you can use it to encapsulate different behavior in separate classes.