6 ms·
Its greatest strength I see is its simplicity. OOP gives a lot of latitude to overcomplicate solutions, and I've found it tends to obscure more obvious solution
by jalapenos 4y ago
Its greatest strength I see is its simplicity. OOP gives a lot of latitude to overcomplicate solutions, and I've found it tends to obscure more obvious solutions to certain problems, e.g. reaching for inheritance to modify behaviours instead doing it by passing functions as arguments, especially among less experienced team members.
The biggest problem in software development is the slow down of value output over time caused by accumulating complexity. Anything that can help keep complexity down is a big win for long term value output.
- kalekold 4y agoIf OOP is over-complicating your code, you're using it wrong. OOP is a tool to manage complexity. Functional programming, in my experience, created much more complicated code because it seems like the authors like to be a clever as possible.
- jalapenos 4y agoOnce you zoom out to the bigger picture of dozens of devs writing the code rather than yourself, its more a matter of "statistically, if I recommend functional over OOP, how simple will the code be a year from now". But granted it needs to be part of a broader pressure to keep things simple, otherwise devs will like you say, find a way to overcomplicate.
- epgui 4y agoAre you confusing "complicated" with "unfamiliar"?
- prmph 4y agoIndeed. Although I have mostly stopped using OOP in most of my code, I sometimes encounter certain classes of problems that are exceedingly complicated to solve in a purely functional way, but that are a breeze to solve using OOP, believe it or not. One can mix functional and OOP code well by compartmentalizing the parts of the code that are in OOP style, and situating it in an overall functional context. For example, the methods of a class can certainly be written in a very functional style, and classes themselves can be instantiated within functions. The mark of a skilled developer is to know which paradigm is the best to solve a particular problem, just like the choice of a data structure can greatly affect simplicity of code to address a problem.
- yen223 4y ago> I sometimes encounter certain classes of problems that are exceedingly complicated to solve in a purely functional way, but that are a breeze to solve using OOP, believe it or not. What kinds of problems, if I may ask?
- pmontra 4y agoI agree. As an example having to create a class for bags of methods that don't fit naturally anywhere is bad. I also despise all the manager, factory, service, command things that emerge more often in OOP projects than in functional ones. I know that they denote well known patterns (if used in that way) but it's clutter, boilerplate, noise around the code that does the job. However functional only is not necessarily better in my experience. Some context. I'm sure I'm biased by a number of factors. One is that I started programming a long time ago in C and I was passing around structs with data and function pointers, so objects. Another one is that I used a number of different languages, currently Elixir, Python, Ruby, some JavaScript, often in the same week for different customers: I like easy to understand code because I this kind of projects with sparse teams is easier to maintain than layer over layer of heavily engineered one (so factories, metaprogramming, etc.) Third, I end up using a minimum common denominator of all those languages plus inescapable and/or great features: I wish all languages had Elixir's pattern matching. This approach works and it reduces the context switch between projects. So, when I'm coding in Elixir sometimes I have to create large data structures and pass them around, piping them to Module1.fn1, Module2.fn2, etc. It's more or less the same than composing methods in OOP, just different syntax. Sometimes those modules become bags of functions too. What's more difficult to do in OOP is to engineer a class to accept arbitrary meaningful methods. In Ruby I often code methods that return a hash (Python dict, JS object) and create a pipeline of .map.map.map in their caller, like a |> pipeline in Elixir. I prefer mixed paradigm approaches, where one can create the few classes needed to represent the few data types that are objects (Elixir's and Erlang's GenServer) and code everything else as functions. I have a couple of Django projects where the only classes are the mandatory database models and management commands. Everything else is functions in modules. That would be much more pleasant to code in Elixir (if it had classes instead of those noisy and uninformative handle_call, handle_cast, start_link.) Ruby has modules too but for some reason customers really like to create classes for everything, even two method ones like class Command def initialize(args) ... end def run ... end end Command.new(args).run which are quite funny to look at. That should be command(args)
- Tainnor 4y ago> Ruby has modules too but for some reason customers really like to create classes for everything, even two method ones like [...] Encapsulation and extraction of complex functionality (yes, you should not do it for trivial one-liners). In Ruby, classes get used a lot for this because, uh, why not, but you might as well just have a module method - it's just that the way modules are used in Ruby makes this slightly awkward because Ruby is after all biased towards "everything is an object". But in, say, Haskell I might write instead: module Command run :: [String] -> IO () run = ... -- some other file import qualified Command ... Command.run args (not that "Command.run" looks like super idiomatic code in Haskell or anything like that, probably you'd structure your code differently, but it's the general principle)