Code stucturing, classes and nested dependencies

Hello all, long time no see. As my projects grow and start to use more and more dependencies, like classes from other projects and so on. How can I keep my projects more structured and modular?

I keep finding myself revisiting old classes to incorporate new behaviour and breaking old behaviour that other projects dependent on.

Any sage advice on how to structure my data so that I can make my classes more self contained and universally useable

Thanks!

Good question! These are my personal values when it comes to structuring code

Public API

When you build a class make sure you clearly define what API is “public” (i.e., to be consumed by other projects) vs internal (used by the library itself). One way to clearly separate public vs internal API is to create two files in your dependency for the class: MyClass and MyClassInternal — you can define your internal functions in the other file

By doing this you can make it easier to read and understand your dependency’s code because the public API will not be interspersed with unrelated code. This may make it more apparent when you go to make a change that it could possibly impact other projects

Single Responsibility

Consider the single responsibility principle. Try to keep your classes (and possibly your entire dependencies) focused on a singular task. If they are doing too many things, consider breaking them into separate, clearly defined modules. By doing this you minimise the amount of interdependencies you have between unrelated code, you make it easier to maintain the dependencies independently of one another, and they can be used separately in your projects (meaning you will have to update fewer projects when you update the public API in one of your modules)

Unit Tests

While tests won’t stop you from making breaking changes, they will catch them early. If you have a test project for each dependency that you can run after making changes, that will allow you to see how things have broken and update your code accordingly. You might even include this in the Main tab for the dependency itself

State and Side Effects

State: does your class hold onto some data? Does it need to? If it doesn’t need to (i.e., the data can be computed on access) get rid of it — you basically have a cache otherwise. And you should only cache something when you have measured the performance impact of not having a cache and it is causing a significant issue

Side effects: try to keep your functions focused on taking their input and producing output. A pure function, a function which does not manipulate external state, is much easier to test and reason about

Naming

I’m a fan of long names. I prefer a function called updateStateAndNotifyListeners to something like update. I like to know at a glance what the entire purpose of a function is, and if it will impact anything beyond the lifetime of its execution


Does anyone else have strategies they adopt to keep things maintainable?

1 Like

What strategies or tools do you recommend for unit tests? I was using a version of CodeaUnit last year, but right now it just makes codea freeze. Are there other tools out there that you like to use in Codea?