-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfactory_method_pattern.rb
77 lines (66 loc) · 2.51 KB
/
factory_method_pattern.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# The Creator class declares the factory method that is supposed to return an
# object of a Product class. The Creator's subclasses usually provide the
# implementation of this method.
class Creator
# Note that the Creator may also provide some default implementation of the
# factory method.
def factory_method
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
# Also note that, despite its name, the Creator's primary responsibility is
# not creating products. Usually, it contains some core business logic that
# relies on Product objects, returned by the factory method. Subclasses can
# indirectly change that business logic by overriding the factory method and
# returning a different type of product from it.
def some_operation
# Call the factory method to create a Product object.
product = factory_method
# Now, use the product.
result = "Creator: The same creator's code has just worked with #{product.operation}"
result
end
end
# Concrete Creators override the factory method in order to change the resulting
# product's type.
class ConcreteCreator1 < Creator
# Note that the signature of the method still uses the abstract product type,
# even though the concrete product is actually returned from the method. This
# way the Creator can stay independent of concrete product classes.
def factory_method
ConcreteProduct1.new
end
end
class ConcreteCreator2 < Creator
def factory_method
ConcreteProduct2.new
end
end
# The Product interface declares the operations that all concrete products must
# implement.
class Product
def operation
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
# Concrete Products provide various implementations of the Product interface.
class ConcreteProduct1 < Product
def operation
'{Result of the ConcreteProduct1}'
end
end
class ConcreteProduct2 < Product
def operation
'{Result of the ConcreteProduct2}'
end
end
# The client code works with an instance of a concrete creator, albeit through
# its base interface. As long as the client keeps working with the creator via
# the base interface, you can pass it any creator's subclass.
def client_code(creator)
print "Client: I'm not aware of the creator's class, but it still works.\n#{creator.some_operation}"
end
puts 'App: Launched with the ConcreteCreator1.'
client_code(ConcreteCreator1.new)
puts "\n\n"
puts 'App: Launched with the ConcreteCreator2.'
client_code(ConcreteCreator2.new)