3 ms·
I'll answer these specifically for Clojure since they vary by language. > encapsulation Encapsulation is primarily a state control concept. It reduces the sur
by grayrest 11y ago
I'll answer these specifically for Clojure since they vary by language.
> encapsulation
Encapsulation is primarily a state control concept. It reduces the surface area of a piece of data to the object it's contained in. The reduction in the amount of code that can touch the data makes it easier to reason about. Clojure works around this by having most of its data be immutable and most functions pure. Debugging is walking up the stack trace to find the change you didn't expect.
> composition
Pure functions compose trivially. Encapsulating data in a class actually limits your composition by design. Using maps lets you re-use the many functions in the standard library pretty much everywhere.
> interfaces
Clojure has an extended version called protocols. It provides an api guarantee but it can be retroactively implemented on Java classes you don't control. Look up the expression problem in clojure for considerably more depth. You can also use multimethods if you want to dispatch on something besides class.
> Patterns
I subscribe to the argument that patterns are workarounds for limitations in a language. Most languages have them but nobody else formalizes them like the Java people. There are ways to accomplish the same objectives, generally with less ceremony.
> SOLID
Single Responsibilty - Concept carries over to functions in a namespace, a good idea in general
Open/Closed - I've always understood this to mean encapsulation, see above.
Liskov substitution - Dynamic languages are duck typed. If you want more assurance you can add something like Schema, which does structual subtyping instead of nominal subtyping.
Interface segregation - Preference in the community is for protocols to be VERY small, usually 1-5 functions.
Dependency inversion - Tends to not come up. Usually when you're designing an API you have a good idea for when a consumer is going to want different behavior. In those cases, you have the API take a function instead.