strategic 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/strategic.svg)](http://badge.fury.io/rb/strategic)
|
4
4
|
[![rspec](https://github.com/AndyObtiva/strategic/actions/workflows/ruby.yml/badge.svg)](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
|