2

O2 a better OOP

 2 years ago
source link: https://dzone.com/articles/o2-a-better-oop
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

O2 a better OOP

For 40 years we've grown accustomed to solving everything with classes and interfaces, but is it the right approach? Are there easier ways to do things?

Nov. 04, 21 · Agile Zone · Opinion

Join the DZone community and get the full member experience.

Join For Free

Since I arguably made 30 million developers angry with my last rant about OOP, I wanted to explain myself a bit more, since I don't hate OOP. In fact, quite the contrary, OOP is amazing, but for me it's like half a brain. It's nice to have half a brain, but it's better to have the whole brain. And if OOP is half the brain, then functional constructs are the rest of the brain.

15332513-jo-man.jpg

Before we proceed, look at this code please. It's basically a Dictionary with a string as its key and a Func (strongly typed lambda object) as its value. Then realise that this is a functional programming structure, implemented in C#. Below is its code in its entirety.

static readonly Dictionary<string, Func<ISignaler, HttpRequest, Task<Node>>> _payloadHandlers =
    new Dictionary<string, Func<ISignaler, HttpRequest, Task<Node>>>
{
    {
        "application/json", RequestHandlers.JsonHandler
    },
    {
        "application/x-www-form-urlencoded", RequestHandlers.UrlEncodedHandler
    },
    {
        "multipart/form-data", RequestHandlers.FormDataHandler
    },
};

The point about the code of course is that it allows me to declare an HTTP request payload function object that's associated with the Content-Type value of my requests. Then as my API is getting HTTP requests, I can handle these according to the request's Content-Type, using a well known and strongly typed "function object" in my code, responsible for transforming any payloads to some internally structured format. I refer to these buggers as "symbolic delegates", and I twice created an entire programming language around the axiom.

Creating something similar to the above without functional programming structs, such as the ability to pass functions around and use these as first class citizens, would be so difficult I'm not even sure if I want to attempt explaining how it should be done. 4/5 different design patterns, 10/15 different classes, abstract factories, and God knows what more. My head hurts already ...

The above construct however is ridiculously simple to extend with custom Content-Type handlers such as the method below illustrates.

public static void RegisterContentType(string contentType, Func<ISignaler, HttpRequest, Task<Node>> functor)
{
    _payloadHandlers[contentType] = functor;
}

Invoking the above method during startup of your application passing in e.g. "application/x-foo-bar" to it, and attaching a function to it, results in that you've got support for a brand new Content-Type in your own applications. Open Closed principle; Check!

However, these aren't OOP constructs. Sure, these are features of C#, having been there for a decade or something - But these Func objects and Action objects that allows us to create strongly typed anonymous "functions" are not a part of OOP. These constructs are often referred to as Lambda objects, and have been a part of functional programming languages since Lisp crawled out of laboratories some 70+ years ago or something. And when you can use such constructs, they often tend to singlehandedly eliminate half a dozen design patterns in your code ...

The problem the way I see it, is that at least as I started programming for real some 20+ years ago, all the fuzz was around OOP. Several of our industry titans warned against it, some of whom I walked you through in my former article, but still everything was all of a sudden supposed to be solved using OOP. This approach is the wrong mindset and leads to suffering. If you don't believe me, try implementing something such as the above method without using my "Symbolic Delegate" approach. Sure it can be done, but the complexity of your code would explode!

The paradox for me, is that this symbolic delegate approach is literally such a powerful construct that I actually "accidentally" ended up creating a complete programming language with the thing; Hyperlambda of course. Not only is it a complete programming language, but it's also got some pretty interesting traits, such as the ability to automate most of the creation of my code, such that I can create constructs that creates Hyperlambda code, wiring up most of my parts automagically together, resulting in less to do for me, since my computer basically does most of my job. A couple of months ago I created a CRM system with Hyperlambda, and when the system was put into production 5 weeks after I started the project, and the customer was happy with the result, the automagic scaffolding process had literally done 83% of my backend job. To put this number into perspective, imagine going to one of your backend devs and telling him the following.

I can make you 5 times more productive

Because that is literally what 83% implies. Of course, what the end developer wants to use his free time doing is up to him. Want to go on vacations 83% of your time? Check! Want to deliver 5 times as many projects with the same resources? Check! However, if you do not take advantage of such constructs, others will, and you will fall behind at some point, since everybody else are 5 times faster than you ...

This is what I refer to as O2. The point in time when functional constructs and OOP constructs are merged together as one, resulting in the ability to use whatever tool happens to be best at the job, according to what problem is at hand. Of course, if you look at the code we started out with, you'll rapidly realise that a huge part of the code is old fashion OOP code. Dependency Injection? Check! SOLID architecture and usage of interfaces? Check! Inheritance (where it makes sense)? Check!

Besides from the occasional Func and Action object you could almost be mislead to believe this is just plain old fashion OOP - However, it's not! Fundamentally it is the synergy of functional programming with OOP programming, resulting in a larger repertoire for you as a software developer, making you better at your job, capable of solving more problems, by applying better solutions. However, to be able to use such constructs you'll need to modify the way you're thinking. I call this modification for "O2", the idea being that it's OOP 2.0 or something ...

O2 is the merging of FP and OOP

... and by applying such constructs, your codebase becomes easier to understand, more extendible, more encapsulated, resulting in that your happiness increases due to less frustration! Work is not the goal, it is the means to achieve some other goal - If some process allows you to work less, while delivering more, it's crucial that you choose it. Even if your only reasons are that you want to spend your 83% spare time coding more ...

One of my inspirations in life is Bruce Lee. Bruce never got stuck in "styles". OOP is one style, but it's not the only style. Be like Bruce Lee ... ^_^


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK