Resolution Order is the unifying algorithm of Doh's architecture. It implements a hybrid multi-inheritance system that works consistently across Packages, Modules, Patterns, and Pods. This unified approach creates a cohesive framework where inheritance and dependency resolution follow the same fundamental principles regardless of context.
Unlike traditional inheritance systems that use either single inheritance (like Java) or class-based multiple inheritance (like C++), Doh's approach is more flexible and dynamic, drawing inspiration from both dependency injection systems and prototype-based inheritance.
Doh's resolution algorithm is governed by four key principles:
These principles create a unified model that applies consistently whether you're working with pattern inheritance, module dependencies, or pod configuration.
All resolution in Doh follows these general steps:
This process creates a flattened, ordered list that determines how properties, methods, configurations, or dependencies are resolved.
The Load System manages how dependencies are resolved and loaded, ensuring they're available in the correct order.
The dependency resolution algorithm is implemented through Doh.expand_dependencies
:
Doh.expand_dependencies = function(dep, packages = Doh.Packages) {
// Recursively expands dependencies to ensure correct load order
}
This function is called internally by Doh.load()
, which is the universal entry point for loading any dependency:
// Load a single dependency
await Doh.load('dependency-name');
// Load multiple dependencies
await Doh.load(['dep1', 'dep2', 'dep3']);
Doh.Module('FeatureModule', [
'core', // Loaded first (and its dependencies)
'await database', // Loaded next and waited for
'async utilities', // Started loading in parallel
'browser?? ui-tools' // Conditionally loaded in browser environments
], function(shared) {
// Module implementation
});
The resolution algorithm ensures these dependencies are loaded in the correct order, respecting both explicit decorators and implicit dependencies.
The Pod system determines how configuration inheritance works, allowing for sophisticated configuration hierarchies.
Pod inheritance is handled by the build_pod
function:
Doh.build_pod = async function(podLocation) {
// Resolves pod inheritance chain and merges configuration objects
}
# pod.yaml
inherits:
- base_config.yaml
- environment/development.yaml
- feature/authentication.yaml
# Custom overrides
database:
host: localhost
port: 5432
Resolution order:
base_config.yaml
(and its inheritance chain)environment/development.yaml
(and its inheritance chain)feature/authentication.yaml
(and its inheritance chain)The Pattern system provides the most sophisticated implementation of resolution order, handling complex inheritance relationships with conditional rules.
The Pattern resolution is implemented through:
Doh.extend_inherits = function(inherits, skip_core = false) {
// Expands the inheritance tree
}
Doh.resolve_inherits_hardening = function(extended, inherits, skip_core) {
// Resolves conditional inheritance and hardening
}
Hard Inheritance (true): Pattern will always be included
inherits: {
BasePattern: true // Always included
}
Soft Inheritance (false): Pattern will only be included if required elsewhere
inherits: {
OptionalPattern: false // Conditionally included
}
Conditional Inheritance (object): Pattern will be included based on complex conditions
inherits: {
ConditionalPattern: { // Included only if DepPattern is also included
DepPattern: true
}
}
Pattern('AdvancedComponent', {
inherits: {
BaseComponent: true, // Hard inheritance
UIComponent: true, // Hard inheritance
DraggableComponent: false, // Soft inheritance
ResizableComponent: { // Conditional inheritance
DraggableComponent: true // If ResizableComponent is included, include DraggableComponent
}
}
});
Pattern('SpecializedComponent', 'AdvancedComponent', {
inherits: {
ResizableComponent: true // Hard inheritance, triggers conditional inheritance
}
});
Resolution for SpecializedComponent
:
object
(implicit base)BaseComponent
UIComponent
DraggableComponent
(included due to ResizableComponent)ResizableComponent
AdvancedComponent
SpecializedComponent
Modules combine dependency resolution with execution order management.
Module loading is handled by Doh.load()
:
// Load a module
await Doh.load('module-name');
// Load multiple modules
await Doh.load(['module1', 'module2']);
The module resolution order affects:
What makes Doh's resolution system truly powerful is how these separate systems interact:
const myComponent = New('SpecializedComponent', {
// Properties
});
The pattern resolution order controls:
Doh.Module('UIModule', ['BaseComponents'], function() {
// Can safely use patterns defined in BaseComponents
Pattern('CustomButton', 'Button', {
// Button is defined in BaseComponents
});
});
# In pod.yaml
DatabaseModule:
connection:
host: production-db.example.com
These configurations are accessible in modules:
Doh.Module('DatabaseModule', function() {
const config = Doh.pod.DatabaseModule.connection;
// Use configuration
});
Doh's unified resolution approach provides key advantages:
Developers learn one core resolution algorithm that works across all Doh systems.
The "last wins" principle creates consistent override behavior in all contexts.
All systems support multiple inheritance/dependencies with conditional inclusion.
The unified model allows different systems to work together coherently.
// Base component
Pattern('Component', {
// Core functionality
});
// Feature components
Pattern('DraggableComponent', {
// Dragging functionality
});
Pattern('ThemeableComponent', {
// Theming functionality
});
// Composed component
Pattern('AdvancedComponent', {
inherits: {
Component: true,
DraggableComponent: true,
ThemeableComponent: true
},
// Additional functionality
});
# base.yaml
database:
driver: postgres
timeout: 30
# development.yaml
inherits:
- base.yaml
database:
host: localhost
debug: true
# production.yaml
inherits:
- base.yaml
database:
host: production-db.example.com
pool_size: 20
Doh's resolution algorithm represents a fundamental innovation in how inheritance and dependency systems can be unified. By applying the same core principles across different contextsβfrom dependency loading to object compositionβDoh creates a consistent, powerful, and flexible framework.
This unified approach enables sophisticated patterns like dynamic composition, conditional inheritance, and feature-based customization throughout the framework.
For more detailed information on specific aspects: