4 ms·
Interesting read! > No more dumping ground folders like “Helper” or “Utility” If you’re organizing by feature and you have one of these helper/utility classes
by dangwu 6y ago
Interesting read!
> No more dumping ground folders like “Helper” or “Utility”
If you’re organizing by feature and you have one of these helper/utility classes that support multiple features, where does it live? Would you consider each utility to be its own “feature”?
- ericaengle 6y agoWe discovered a lot of cases would be unique, so we do try to evaluate a "best" case when it comes to each move. Keeping that in mind, if a feature has a shared helper across components within the /Feature folder, we'll have a /Shared folder within to capture these files. At a top level, we would encourage a new /Feature folder since most likely it will have tests or be important enough to merit a folder rather than squishing it into another /Feature folder. We're optimizing for visibility too, so having it's own /Feature folder helps with that.
- dangwu 6y agoThanks! And am I correct in assuming Slack just has a single target for the iOS app (App), then one for each App Extension? So the root source folders map 1:1 to build targets?
- ericaengle 6y agoYes! that's the idea, or at least what we've worked to achieve
- drawkbox 6y agoIt depends on how many projects you have. A place like Slack has only one client/product really when it comes down to it, so they can get pedantic about it and look down on smart reuse across projects with robust tested libs on top of standard libs that are necessary to increase production and stability/security etc. If you work at an agency, or game company shipping many games, there will always be a "core" library or "base" library that has Helpers and Utility. Good consistent projects wanted tested and solid parts. Every game has a common lib of core tools like maths, vector tools, prediction, data structures and many more. There is such a broad difference in coding on one platform for one company for one product compared to shipping many companies (or many internal projects) on many platforms for many products. Even standard libraries for platforms are essentially a Helper/Utility really when it comes down to it: .NET Core, Python standard lib, standard node, C++ distributable etc. There will be common core tasks across a project, product, company or platform for most teams with many projects to manage. If you don't have common libs with common helpers/utilities in large sets of products, technical debt and maintenance become a nightmare. In projects we work on these are core/base libs that are submodules in git and are essentially the 'tech' across projects where the project/product itself is the unique implementation for that product. Anything common or generic gets put in the core 'tech'. Every single game studio will have these as well as agencies if they are organized and produce quality relatively fast and consistent. If "Happiness is a freshly organized codebase" they must have common tested parts that are ship tested. This is really just Slack talking specifically about mature products at a company that only has one product. It isn't reality at places that have many projects, products, companies, clients etc. Pretending they are the same is a bit elitist.
- honkycat 6y agoI always argue adding "helper" or "util" adds nothing to the description of a file/module/class and is better left off
- seph-reed 6y agoUtility - few or no dependencies. Absolutely no dependencies specific to the project. (array flattener, 2-way map, etc) Helper - function which makes some really common project specific code more DRY (createApiError, genCommonConfig, etc)
- ravenstine 6y agoI'd also consider a Helper to be something that may have application-awareness. Whereas, as you stated, a Utility would have no serious dependencies and is otherwise "dumb".
- nilkn 6y agoI feel like these names convey a lot, though. When I see something like this, I immediately expect it to not do any of the following: (1) contain core logic or define primary classes/types/records; (2) have dramatic side effects; (3) be hard to test; (4) reference or depend on other parts of the codebase; (5) do anything controversial in general. I’d say I’d expect a “utility” to adhere to these conditions more strongly than a “helper,” which might be a bit more entangled with application logic.
- _bxg1 6y agoI actually think it's vitally important to have "dumping ground" locations for things that aren't fully figured-out yet. If I'm working on a new thing and I have something that's relevant in multiple files but I'm not sure where it should go, or even whether it will stick around, I don't want to have to come to a screeching halt just to make a taxonomic decision about something that's still a work in progress. The key, of course, is going back and categorizing those things later once you do have an idea of where they should go.
- ryanianian 6y ago> The key, of course, is going back and categorizing those things later once you do have an idea of where they should go. Yes, but in my experience this is rarely done. It's put off until it gets so convoluted that it introduces bugs. The same is true even if you do avoid dumping-grounds: you need to examine the project's state somewhat regularly to ensure it still makes sense. Where code lives can be as important as the code itself and thus deserves at least occasional review and change.
- allenu 6y agoTotally agree. So much of programming and designing is figuring out what pattern your code is falling into and what stuff "is" or "means". I believe it's totally okay to name things utilities when you haven't yet established a common pattern or understanding of it. Naming things is hard and spending so much time on it and organizing things can often block you from progressing to a place where you DO have more information and can intelligently name things. You'll always be juggling unknowns, so it's okay to have dumping grounds here and there, so long as over time you clean them up as you gain more info.
- _bxg1 6y agoI recently started working within a Python codebase, and one of the things I really like about it (not sure whether this is standard Python practice) is that most directories have a "common.py" file in them. So if you just want to put something somewhere real quick, you can elevate it to exactly the appropriate directory-level instead of going to a single, global "utils" file. It's a neat pattern.
- lmm 6y agoIf they don't have anything in common, yes. If you have one collection helper method, one time helper method and one auth helper method, far better to put those in a collection class, a time class and an auth class than bundle them up as a "utils" class.