4 ms·
To be clear, static typing is the zenith of of compiler optimizations and in many ways the programming "ideal," however in the context of loosely typed language
by j42 11y ago
To be clear, static typing is the zenith of of compiler optimizations and in many ways the programming "ideal," however in the context of loosely typed languages (and their OOP abstractions) and I think the author is missing a significant use-case.
Separation of responsibility/decoupling on the service level are good principles to begin with, but in an OOP paradigm where you are defining/exposing classes and methods, these keywords are really useful for grouping functionality when you adhere to "contract-driven development."
When used correctly they help you abstract the interface for your class (ie, the public implementation-agnostic methods that provide interoperability between the service and the program as a whole) and separate it from methods only designed for internal use (within the class itself).
Often times those abstractions are essential (DRY principles) and the class is the proper place to encapsulate them, however you wish to clearly designate that "this method is self-modifying, limited in scope, and does not interact with or is required by any other class in any meaningful way," and for that it's quite useful.
- chipsy 11y agoA nice standard reply. But how do you verify that your usage has the impact you think it does? When I started estimating the complexity of my code - just using rule of thumb and line counts - I found that most uses of classes were unjustified. The "right size" of a class was quite large, especially so in the top level of an application.
- j42 11y agoWell, I can't speak necessarily for the way you write or view code, but for my process I've found its impact intrinsic and clearly definable. First I should note that I follow a few basic principles/sets of principles when programming loosely-typed imperative languages. 1) Single-responsibility for classes and methods, with each method coming in around <= 20 lines. In total the majority of my classes in enterprise level applications (supporting 100's of millions of users & responding to internal events with meta/statistical analysis) rarely grow beyond 200 lines per class. Usually whenever I hit the 2-500 line range I'll find that many methods can be logically abstracted to a few core traits in order to take advantage of multiple-inheritances without overcomplicating the central registrar or DI patterns. 2) I build an interface before building a class--the interface defines what methods will be available to the application/world context (thinking as per an API interface), as well as what type(s) should be received and what type(s) should be returned. By type hinting/checking at this stage and ensuring conformance to an interface, you can swap out implementations easily later, as well as have a general map or "spec" before you really start hammering the nails--this helps in staying organize and weeding out bad architecture decisions early. 3) I keep these public methods simple, so that I can clearly detect failure points and debug based on input/return types for the 'service' as a whole, and then I use protected methods internally similarly to data pipes in functional programming; each method is clearly named, has a specific transformation it applies, and acts on a series of (n) objects by mapping transformations vs iterative loops which precludes un-terminated conditionals and other type-juggling weirdness. This all results in software that's very concise (IMHO), runs well, and is quite simple to test. I can inherit any class from a testclass, in order to test the protected data pipes with any sample streams. I can verify the I/O types for all interfaced methods of the class (via functional tests), and tie it all together neatly in knowing that I can pull up any file and clearly differentiate between what formats/returns/transports data, and what mutates it and/or the "state." The process is by no means perfect and I continue to learn in my pursuits as do we all, however this structure has worked well for me consistently on the types of large projects where others have failed, and in that context I feel it's worth expounding.