strategic 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +10 -8
- data/lib/strategic.rb +7 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d76d0987f4534352de4fb52f025547a0ef37cad16a9452f1fd78da71606a3bae
|
4
|
+
data.tar.gz: 389a399d74c94352cf2165a8975b0b8d5886c782d08614c8b674ae0bd329c2a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5aa4d886c61f6daf162ac9a7dbd19635fb20cb0c9c9cef437998d8496e0e75f4c0381a7abe2c887ba794398ca4522489702cfa644cd18d180bb9cf95813a8725
|
7
|
+
data.tar.gz: 2243df9a574cbf09d708f16ef5d6c2bbc2d621e1932c50e68b081402ad19c49ab341dfdd07b5fd5461cbe1ad0ed17cf1898546d62e09b4e254b4ed3d9fbf8d89
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 1.2.0
|
4
|
+
|
5
|
+
- `default_strategy` default value will be `'default'`, assuming a `model_namespace/default_strategy.rb` file with `DefaultStrategy` class
|
6
|
+
- `new_with_default_strategy` class method (instantiating with `'default'` strategy if not configured or `default_strategy` class method value if configured)
|
7
|
+
|
3
8
|
## 1.1.0
|
4
9
|
|
5
10
|
- Generate `strategy_name` attribute on `Strategic` class if it does not already exist like in the case of a Rails migration column
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Strategic 1.
|
1
|
+
# Strategic 1.2.0
|
2
2
|
## Painless Strategy Pattern in Ruby and Rails
|
3
3
|
[](http://badge.fury.io/rb/strategic)
|
4
4
|
[](https://github.com/AndyObtiva/strategic/actions/workflows/ruby.yml)
|
@@ -28,7 +28,7 @@ code (Open/Closed Principle).
|
|
28
28
|
externalizing all logic concerning algorithmic variations into separate strategy
|
29
29
|
classes that are easy to find, maintain and extend while honoring the Open/Closed Principle and avoiding conditionals.
|
30
30
|
|
31
|
-
In summary, if you make a class called `TaxCalculator` strategic by including the `Strategic` mixin module, now you are able to drop strategies under the `tax_calculator` directory sitting next to the class (e.g. `tax_calculator/us_strategy.rb`, `tax_calculator/canada_strategy.rb`) while gaining extra [API](#api) methods to grab strategy names to present in a user interface (`.strategy_names`), set a strategy (`#strategy=(strategy_name)` or `#strategy_name=(strategy_name)`), and/or instantiate `TaxCalculator` directly with a strategy from the get-go (`.new_with_strategy(strategy_name, *initialize_args)`). Finally, you can simply invoke strategy methods on the main strategic model (e.g. `tax_calculator.tax_for(39.78)`).
|
31
|
+
In summary, if you make a class called `TaxCalculator` strategic by including the `Strategic` mixin module, now you are able to drop strategies under the `tax_calculator` directory sitting next to the class (e.g. `tax_calculator/us_strategy.rb`, `tax_calculator/canada_strategy.rb`) while gaining extra [API](#api) methods to grab strategy names to present in a user interface (`.strategy_names`), set a strategy (`#strategy=(strategy_name)` or `#strategy_name=(strategy_name)`), and/or instantiate `TaxCalculator` directly (`.new(*initialize_args)`), with default strategy (`.new_with_default_strategy(*initialize_args)`), or with a strategy from the get-go (`.new_with_strategy(strategy_name, *initialize_args)`). Finally, you can simply invoke strategy methods on the main strategic model (e.g. `tax_calculator.tax_for(39.78)`).
|
32
32
|
|
33
33
|
### Example
|
34
34
|
|
@@ -98,9 +98,9 @@ tax_calculator = TaxCalculator.create(args) # args include strategy_name
|
|
98
98
|
tax = tax_calculator.tax_for(39.78)
|
99
99
|
```
|
100
100
|
|
101
|
-
Default strategy for a strategy name that has no strategy class is `nil`
|
101
|
+
Default strategy for a strategy name that has no strategy class is `nil` unless `DefaultStrategy` class exists under the model class namespace or `default_strategy` class attribute is set.
|
102
102
|
|
103
|
-
|
103
|
+
This is how to set a default strategy on a strategic model via class method `default_strategy`:
|
104
104
|
|
105
105
|
```ruby
|
106
106
|
class TaxCalculator
|
@@ -122,7 +122,7 @@ If no strategy is selected and you try to invoke a method that belongs to strate
|
|
122
122
|
Add the following to bundler's `Gemfile`.
|
123
123
|
|
124
124
|
```ruby
|
125
|
-
gem 'strategic', '~> 1.
|
125
|
+
gem 'strategic', '~> 1.2.0'
|
126
126
|
```
|
127
127
|
|
128
128
|
### Option 2: Manual
|
@@ -130,7 +130,7 @@ gem 'strategic', '~> 1.1.0'
|
|
130
130
|
Or manually install and require library.
|
131
131
|
|
132
132
|
```bash
|
133
|
-
gem install strategic -v1.
|
133
|
+
gem install strategic -v1.2.0
|
134
134
|
```
|
135
135
|
|
136
136
|
```ruby
|
@@ -142,7 +142,7 @@ require 'strategic'
|
|
142
142
|
Steps:
|
143
143
|
1. Have the original class you'd like to strategize include `Strategic` (e.g. `def TaxCalculator; include Strategic; end`
|
144
144
|
2. Create a directory matching the class underscored file name minus the '.rb' extension (e.g. `tax_calculator/`)
|
145
|
-
3. Create a strategy class under that directory (e.g. `tax_calculator/us_strategy.rb`)
|
145
|
+
3. Create a strategy class under that directory (e.g. `tax_calculator/us_strategy.rb`) (default is assumed as `tax_calculator/default_strategy.rb` unless customized with `default_strategy` class method):
|
146
146
|
- Lives under the original class namespace
|
147
147
|
- Includes the `Strategic::Strategy` module
|
148
148
|
- Has a class name that ends with `Strategy` suffix (e.g. `NewCustomerStrategy`)
|
@@ -158,7 +158,8 @@ Steps:
|
|
158
158
|
|
159
159
|
These methods can be delcared in a strategic model class body.
|
160
160
|
|
161
|
-
- `::default_strategy`: sets default strategy as a strategy name string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
|
161
|
+
- `::default_strategy(strategy_name)`: sets default strategy as a strategy name string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
|
162
|
+
- `::default_strategy`: returns default strategy (default: `'default'` as in `DefaultStrategy`)
|
162
163
|
- `::strategy_matcher`: custom matcher for all strategies (e.g. `strategy_matcher {|string| string.start_with?('C') && string.end_with?('o')}`)
|
163
164
|
|
164
165
|
#### Class Methods
|
@@ -166,6 +167,7 @@ These methods can be delcared in a strategic model class body.
|
|
166
167
|
- `::strategy_names`: returns list of strategy names (strings) discovered by convention (nested under a namespace matching the superclass name)
|
167
168
|
- `::strategies`: returns list of strategies discovered by convention (nested under a namespace matching the superclass name)
|
168
169
|
- `::new_with_strategy(string_or_class_or_object, *args, &block)`: instantiates a strategy based on a string/class/object and strategy constructor args
|
170
|
+
- `::new_with_default_strategy(*args, &block)`: instantiates with default strategy
|
169
171
|
- `::strategy_class_for(string_or_class_or_object)`: selects a strategy class based on a string (e.g. 'us' selects UsStrategy) or alternatively a class/object if you have a mirror hierarchy for the strategy hierarchy
|
170
172
|
|
171
173
|
#### Instance Methods
|
data/lib/strategic.rb
CHANGED
@@ -30,6 +30,7 @@ module Strategic
|
|
30
30
|
else
|
31
31
|
klass.include(ExtraRubyMethods)
|
32
32
|
end
|
33
|
+
klass.default_strategy 'default'
|
33
34
|
end
|
34
35
|
|
35
36
|
module ExtraRailsMethods
|
@@ -111,6 +112,12 @@ module Strategic
|
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
115
|
+
def new_with_default_strategy(*args, &block)
|
116
|
+
new(*args, &block).tap do |model|
|
117
|
+
model.strategy = nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
114
121
|
def new_with_strategy(string_or_class_or_object, *args, &block)
|
115
122
|
new(*args, &block).tap do |model|
|
116
123
|
model.strategy = string_or_class_or_object
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strategic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Maleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.8.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rake-tui
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
description: |
|
126
140
|
if/case conditionals can get really hairy in highly sophisticated business domains.
|
127
141
|
Domain model inheritance can help remedy the problem, but you don't want to dump all
|
@@ -167,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
181
|
- !ruby/object:Gem::Version
|
168
182
|
version: '0'
|
169
183
|
requirements: []
|
170
|
-
rubygems_version: 3.
|
184
|
+
rubygems_version: 3.3.1
|
171
185
|
signing_key:
|
172
186
|
specification_version: 4
|
173
187
|
summary: Painless Strategy Pattern for Ruby and Rails
|