An Illustration Of Decoupling - Part I of II
This is a simplified, real-world, design problem that caused rather significant division within a small software development team. Personally, I thought the best answer was rather obvious but I'd like you to decide.
Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
},
],
outputRoot: 'my/output/',
}
Resulting files:
my/output/input0.sml.jpg
my/output/input0.med.jpg
my/output/input0.lge.jpg
my/output/input1.sml.jpg
my/output/input1.med.jpg
my/output/input1.lge.jpg
Add 'sourceRoot' to each input that identifies the portion of the sourceFile that should be ignored. The absence of a 'sourceRoot' will cause default behaviour which is to use the entire path up to the last '/'.
Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
sourceRoot: 'my/',
},
{
sourceFile: 'my/path1/input1.jpg',
sourceRoot: 'my/',
},
],
outputRoot: 'my/output/',
}
Resulting files:
my/output/path0/input0.sml.jpg
my/output/path0/input0.med.jpg
my/output/path0/input0.lge.jpg
my/output/path1/input1.sml.jpg
my/output/path1/input1.med.jpg
my/output/path1/input1.lge.jpg
Add 'outputPrefix' to each input that indicates the path (within outputRoot) to write resulting files. Absence of 'outputPrefix' would indicate the current default behaviour (i.e. use last part of path).
Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
outputPrefix: 'alt0/result0.',
},
{
sourceFile: 'my/path1/input1.jpg',
outputPrefix: 'alt1/result1.',
},
],
outputRoot: 'my/output/',
}
Resulting files:
my/output/alt0/result0.sml.jpg
my/output/alt0/result0.med.jpg
my/output/alt0/result0.lge.jpg
my/output/alt1/result1.sml.jpg
my/output/alt1/result1.med.jpg
my/output/alt1/result1.lge.jpg
Have a think about which proposal you prefer and then read part II which outlines the pros and cons of each solution, and more.
Context
Consider a web service that reads a file from storage and produces one or more files as output. For example, lets say it resizes an image to various, standard sizes: sml, med, lge. The service may process multiple input files in a batch-style request. File storage identifies a file with a string that may contain forward slashes '/' that indicate a folder structure only by convention. So folders don't need to be created or deleted. The input consists of an array of objects (each containing a 'sourceFile' field), and a single 'outputRoot'.Current Implementation
The current implementation operates as described below.Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
},
{
sourceFile: 'my/path1/input1.jpg',
},],
outputRoot: 'my/output/',
}
Resulting files:
my/output/input0.sml.jpg
my/output/input0.med.jpg
my/output/input0.lge.jpg
my/output/input1.sml.jpg
my/output/input1.med.jpg
my/output/input1.lge.jpg
Problem:
Clients need more control over how outputs are arranged to facilitate more robust batchingProposal 1:
This originated from the author of the current solution who has worked in the business domain before and considered the path in each sourceFile input to have significant contextual value.Add 'sourceRoot' to each input that identifies the portion of the sourceFile that should be ignored. The absence of a 'sourceRoot' will cause default behaviour which is to use the entire path up to the last '/'.
Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
sourceRoot: 'my/',
},
{
sourceFile: 'my/path1/input1.jpg',
sourceRoot: 'my/',
},
],
outputRoot: 'my/output/',
}
Resulting files:
my/output/path0/input0.sml.jpg
my/output/path0/input0.med.jpg
my/output/path0/input0.lge.jpg
my/output/path1/input1.sml.jpg
my/output/path1/input1.med.jpg
my/output/path1/input1.lge.jpg
Proposal 2:
This originated from a developer who was not that familiar with the business domain and also noticed some other problems with the current solution.Add 'outputPrefix' to each input that indicates the path (within outputRoot) to write resulting files. Absence of 'outputPrefix' would indicate the current default behaviour (i.e. use last part of path).
Request:
{
inputs: [
{
sourceFile: 'my/path0/input0.jpg',
outputPrefix: 'alt0/result0.',
},
{
sourceFile: 'my/path1/input1.jpg',
outputPrefix: 'alt1/result1.',
},
],
outputRoot: 'my/output/',
}
Resulting files:
my/output/alt0/result0.sml.jpg
my/output/alt0/result0.med.jpg
my/output/alt0/result0.lge.jpg
my/output/alt1/result1.sml.jpg
my/output/alt1/result1.med.jpg
my/output/alt1/result1.lge.jpg
Have a think about which proposal you prefer and then read part II which outlines the pros and cons of each solution, and more.
Comments
Post a Comment