Urgh. I was hoping this would be pushing grouping the code related to a given feature. I guess when you’re using a dynamic language the language isn’t giving you much help, so you might as well implement your own object/delegate system on top of it.
What if organizing code by class wasn’t in opposition to organizing code by features? What if instead of injecting code into random classes from random places, we organized our classes to reflect our features?
The trouble with organizing classes to reflect features is that it invariably makes a large project harder for newcomers to understand, with rippling effects on its ability to recruit new people, and therefore its longevity as a whole. Walking the tightrope between coupling and cohesion is hard; in practice you end up either tightly coupled or loosely cohesive, and either way newcomers are up shit creek.
My preferred approach is to skip classes altogether and focus on just functions and features (layers) as my units of organization. The key benefit of this approach is that newcomers can easily build versions of the codebase with incremental subsets of features. That leaves them with less code to read at the start, with confidence that dropped features aren’t in the binary they’re currently running.
There’s been steady, but small, progress on it in CompSci. The idea is you somehow model your code in a way that pertains to specific features, you can add/remove parts of the model, and the app is generated/maintained with the right features. There’s also overlap with component-based software engineering which was an early way to do this.
I’m not sure what will ultimately work but most effort is going into components. Combining components with generic, functional code is probably easiest route as Smalltalk and Haskell can be quite easy to modify without breakage. Then, have a formal specification for modeling that checks things such as equivalence of data structures, order of operations, interface requirements, and so on. These get translated into the correct code after a modification to specification. Partial specifications used when something is feature-specific. Just create code with a tie-in spec that can be automatically combined with existing one to transform that code in a way suitable for integration.
That reminds me of something I read about a big company (Google, Facebook, Netflix?) where developers could add features to a web app but it had to be turned on and off by a global variable at run time, so they basically just maintained a big list of bools for their 10s or 100s of features, but when something broke they could turn features off in one place until they worked out where the problem was. I’m not sure how they handled dependencies, if feature C relies on B which relies on A.
That’s interesting. That is similar to what FOP people describe as the goal in academic papers. They just wanted more guarantees and tooling. It’s why they did more.
Feature flags (or feature toggles). You could also specify target users who would see those features (I want 1% of the folks that appear to be coming from California). There are also (at least) two companies that offer products for this: LaunchDarkly and Split.io, since this can start to get complicated really quickly.
Rather than each class knowing a lot about how a feature is put together, the classes could be small and focused on representing their data. A feature could grow or shrink within the context of every object it needed.
This sounds a lot like making a POD and then writing modules with functions over those datatypes, i.e. one module per feature. When did people forget how to program?
I don’t think it’s a parody, and I believe that Jim has been thinking about this stuff for a while. I think his approach emphasises the object in OOP, and he adds behaviour directly to objects as and where required.
If anything, the idea of improving locality through organising code by features is intriguing. I’m not sure about the implementation, I haven’t looked at it closely. I also have misgivings about it because even in a regular OOP setup, everybody usually starts out by aligning classes closely with features, but it doesn’t last long because features interact, and the complexity of interaction between them starts to ripple through the code, leading to the situation described in the post where different parts of the code pertaining to a single feature are strewn through the code base.
Yup. Controlling locality has been the best thing I’ve done for my projects.
If a new developer jumps in, it is much easier to communicate about the features because the behavior necessary is in one place.
Because people typically align their data classes with all the behavior necessary for a feature, the implementation gets smeared across the application. Cleavage points between what belongs together and what does not becomes harder to understand.
Urgh. I was hoping this would be pushing grouping the code related to a given feature. I guess when you’re using a dynamic language the language isn’t giving you much help, so you might as well implement your own object/delegate system on top of it.
What if organizing code by class wasn’t in opposition to organizing code by features? What if instead of injecting code into random classes from random places, we organized our classes to reflect our features?
The trouble with organizing classes to reflect features is that it invariably makes a large project harder for newcomers to understand, with rippling effects on its ability to recruit new people, and therefore its longevity as a whole. Walking the tightrope between coupling and cohesion is hard; in practice you end up either tightly coupled or loosely cohesive, and either way newcomers are up shit creek.
My preferred approach is to skip classes altogether and focus on just functions and features (layers) as my units of organization. The key benefit of this approach is that newcomers can easily build versions of the codebase with incremental subsets of features. That leaves them with less code to read at the start, with confidence that dropped features aren’t in the binary they’re currently running.
There’s actually a programming paradigm that does exactly this:
https://en.wikipedia.org/wiki/Feature-oriented_programming
There’s been steady, but small, progress on it in CompSci. The idea is you somehow model your code in a way that pertains to specific features, you can add/remove parts of the model, and the app is generated/maintained with the right features. There’s also overlap with component-based software engineering which was an early way to do this.
https://en.wikipedia.org/wiki/Component-based_software_engineering
I’m not sure what will ultimately work but most effort is going into components. Combining components with generic, functional code is probably easiest route as Smalltalk and Haskell can be quite easy to modify without breakage. Then, have a formal specification for modeling that checks things such as equivalence of data structures, order of operations, interface requirements, and so on. These get translated into the correct code after a modification to specification. Partial specifications used when something is feature-specific. Just create code with a tie-in spec that can be automatically combined with existing one to transform that code in a way suitable for integration.
That reminds me of something I read about a big company (Google, Facebook, Netflix?) where developers could add features to a web app but it had to be turned on and off by a global variable at run time, so they basically just maintained a big list of bools for their 10s or 100s of features, but when something broke they could turn features off in one place until they worked out where the problem was. I’m not sure how they handled dependencies, if feature C relies on B which relies on A.
That’s interesting. That is similar to what FOP people describe as the goal in academic papers. They just wanted more guarantees and tooling. It’s why they did more.
Feature flags (or feature toggles). You could also specify target users who would see those features (I want 1% of the folks that appear to be coming from California). There are also (at least) two companies that offer products for this: LaunchDarkly and Split.io, since this can start to get complicated really quickly.
It’s extremely unclear to me what this even does.
This sounds a lot like making a POD and then writing modules with functions over those datatypes, i.e. one module per feature. When did people forget how to program?
Is this meant to be a parody of rails coders? Might need a tag.
I don’t think it’s a parody, and I believe that Jim has been thinking about this stuff for a while. I think his approach emphasises the object in OOP, and he adds behaviour directly to objects as and where required.
If anything, the idea of improving locality through organising code by features is intriguing. I’m not sure about the implementation, I haven’t looked at it closely. I also have misgivings about it because even in a regular OOP setup, everybody usually starts out by aligning classes closely with features, but it doesn’t last long because features interact, and the complexity of interaction between them starts to ripple through the code, leading to the situation described in the post where different parts of the code pertaining to a single feature are strewn through the code base.
Yup. Controlling locality has been the best thing I’ve done for my projects. If a new developer jumps in, it is much easier to communicate about the features because the behavior necessary is in one place. Because people typically align their data classes with all the behavior necessary for a feature, the implementation gets smeared across the application. Cleavage points between what belongs together and what does not becomes harder to understand.