-
Notifications
You must be signed in to change notification settings - Fork 1
Development: Glossary
❗❗❗DISCLAMER❗❗❗
This glossary makes sense only in the context of this library. Do not use it as an authoritative source for term definitions outside of convenient_service. Thanks.
TODO
Dynamic dependencies are dependencies that can be loaded on demand by the end-user when a plugin that depends on them is required.
The lib is completely functional without them.
Own method or const means a method or const that is defined directly in the caller class. For example:
##
# @example Open an interactive Ruby console with already loaded `convenient_service`:
# cd convenient_service
# task playground
#
module A
FOO = :foo
module B
BAR = :bar
end
end
ConvenientService::Utils::Module.get_own_const(A::B, :FOO)
# nil, since FOO is defined in A, not in B
ConvenientService::Utils::Module.get_own_const(A::B, :BAR)
# :bar (value of A::B::BAR), since BAR is defined directly in B
TODO
TODO
A plugin is a combination of concerns and middlewares in order to extend/modify/restrict the functionality of services and/or their parts.
Actually, a plugin can be constructed only from a sole concern, or just from one middleware.
The only requirement - it must strictly follow the Separation of Concerns principle.
Here is some example plugins:
-
assigns_attributes_in_constructor
. -
caches_return_value
. -
has_result_steps
. -
raises_on_double_result
. -
wraps_result_in_db_transaction
.
As their names state, each of them has a Single Responsibility that is easy to understand with minimal context.
Plugins are grouped by the broadness of their applicability.
- Common - can be applied to any type of entity, e.g: Service, Result, Step, Internals, etc.
- Service - plugins that make sense only in the service scope.
- Result - same as previous, but for results.
- Internals - effect of Service, Result, Step plugins may be visible to the end-users, while Internals plugins outcome is always hidden.
Plugins may depend on other plugins.
Static dependencies are dependencies that are always loaded whenever require "convenient_service"
is called.
The lib is NOT functional without them.
A Sequence diagram is an interaction diagram that shows how processes operate with one another and in what order.
Sources:
-
"Sequence diagrams" by mermaid (a tool to create diagrams in Markdown-inspired text definitions).
-
"Unified Modeling Language (UML) | Sequence Diagrams" by GeeksForGeeks.
-
"Explore the UML sequence diagram" by IBM developer.
-
"Sequence Diagram Tutorial – Complete Guide with Examples" by Creately.
Examples:
TODO
TODO
Support class, module, or concern is a behavior that is very similar to util by its nature, it also does one logical thing and should be easily extractable between projects, but it can NOT be expressed as a pure function.
Check convenient_service/lib/convenient_service/support for examples.
An util is a pure function that does exactly one thing.
In a general case, it should be easy to extract and reuse utils in the different projects (so they should be context-independent as well).
For example, it is a relatively common task to look for the last item in an array that matches a condition, but Ruby's Array and Enumerable have no built-in methods for that.
Such a case is a great candidate for util:
module ConvenientService
module Utils
module Array
class FindLast < Support::Command
attr_reader :array, :block
def initialize(array, &block)
@array = array
@block = block
end
def call
array.reverse.find(&block)
end
end
end
end
end
module ConvenientService
module Utils
module Array
class << self
def find_last(...)
FindLast.call(...)
end
end
end
end
end
array = [1, 2, 3, 4, 5]
array.find { |item| item % 2 == 0 }
# => 2
ConvenientService::Utils::Array.find_last(array) { |item| item % 2 == 0 }
# => 4