What is the context in object-oriented programming?

Kajetan
Level Up Coding
Published in
6 min readOct 6, 2020

--

Photo by Cesar Carlevarino Aragon on Unsplash

This question changed my view on object-oriented programming forever. It was a few years ago when I accidentally found the answer I hadn’t even sought. Eventually, however, it was surprisingly simple, yet enlightening. Unlike me back then, I assume you aren’t here by mistake, so I hope to shed some light on the concept of context and, ideally, inspire you to build better-designed software.

Before I start, let me mention that you shouldn’t expect much academic theory (in fact, you shouldn’t expect it at all) and terms used in their strict book definitions. My aim is not to give one of those dull lectures devoid of practical usage, but to share my knowledge and understanding of the context in the… context of OOP, and how it helps to design clearer architecture and more user-friendly APIs, libraries, etc. Let me emphasize “share” as I’m far from “teaching” you the one and only way to understand this topic.

All code samples are written in Kotlin for two reasons. Number one — currently it’s the programming language in which I write the most. Moreover, I got the idea for this article while working on my set of Android libraries, thus it’s easier to find/come up with real-world examples. The second reason is that the syntax of Kotlin handles using contexts and defining DSL-like tools in the most impressive and friendly manner I’ve seen. Yeah, Kotlin fanboi confirmed. 😅 Okay, that’s a long preface. Let’s get started.

The definition

I know I’ve just promised to avoid academic theory, but the dictionary definition is a good point to start from, actually, so forgive me. The Cambridge English dictionary provides us with two definitions:

The influences and events related to a particular event or situation.

The text or speech that comes immediately before and after a particular phrase or piece of text and that influence how it is used and what it means.

The latter is a little bit more fitting to what we’re trying to grasp here. As for now, we can try to translate it literally to Geekish language:

The block of code that surrounds a particular statement or expression and that influences its syntax and implementation.

(Let me know in the comments whether I translated it correctly or made some syntax error. Geekish is not my mother tongue.) If we’d finished here, you’d basically end up with the understanding I had before I truly understood. Basic. If you’ve come for more, feel invited to the next section.

That moment

I’ve been programming in Java for around 5 years then. Generally, I quite got and loved the concept of object-oriented programming. My middle name was Abstraction, my third name was Encapsulation, my fourth name was Inheritance and my fifth name was Polymorphism. Yes, I used to have a long name back then. So what else could I have learned?

A lot.

I worked on Yet Another SQL Query Builder Library (don’t google it, I’ve come up with this name now) when he came…

Enters Senior Developer

Splits the code of YASQLQBL into two displays and reads it from top to bottom with one eye, and bottom to top with the other eye. Simultaneously.

Photo by Max Duzij on Unsplash

“Hey, it’s pretty nice. But look, your class hierarchy is almost completely flat,” he noticed.

“Hm. Yes, it is. But what does a query builder need besides one class and set of its methods?” I asked curiously.

“To work properly? Nothing. To be more user friendly, less error-prone, and decently designed? Contexts.

“Contexts? What do you mean?”

“Can you write the “having” clause before the “where” clause in SQL?”

“No, it’ll cause a synta…”

“Can you write the “having” clause before the “where” clause in your builder?”

“Well… Yes, but who would write such a statement?…”

“Any programmer without enough coffee in their veins.”

“… Besides, it’ll cause a syntax error, too! But um… at… runtime?” I got embarrassed.

“Exactly. Wouldn’t it be great to have a compile-time error in such cases?

I nodded, “So how will contexts solve this problem?”

“Quickly and easily. Stay awhile and listen. Context is not just a block of code with its accessible variables, parameters, etc. The context determines what you can and cannot do. The context tells you how to perform particular operations. A whole class is a context. A method is a little context. All scopes are contexts in themselves!”

“Wow, I never thought of it that way! It seems I didn’t understand more than a computer. I saw classes as possibly extendable containers of fields and methods. Nothing more, nothing less. I used them mostly to stick to the DRY principle. I didn’t see any idea behind this. After all, it’s just a sequence of bits.”

“True. That’s why programming languages were invented. To provide a readable and considerably easy to understand interface for humans. And as we generally prefer to think using words, concepts, and ideas rather than numbers, equations, and mathematical formulas, we got object-oriented programming”

… Yes, I colorized it a little bit, I admit. 😉

Implementation

Inspired by Senior Developer I divided SQL clauses into separate classes, thereby providing an appropriate context for each of them. And the results were more than satisfactory. While methods can only force passing arguments of the compatible types, classes can force invoking methods of the appropriate context. The final version of the library looked more or less like the following:

Another great advantage of context awareness is that interfaces won’t become polluted. Despite the fact that using extension functions/methods in Kotlin and C# is very useful and recommended, it may lead to the temptation of overusing it. Here’s an example of what I mean:

While it could be a really nice part of some time-related DSL-like library, making these extension functions globally accessible wherever Int is used is a bad idea. Let’s extend the previous example so you’ll see yourself why:

Photo by Paul Felberbauer on Unsplash

The last doesn’t make any sense. Both extensions could be sweet but only if they existed in dedicated contexts. Otherwise, it’ll be misleading and prone to misuse. Time can be represented by a number, but not every number represents time. The same applies to units of information.

While designing the Android dialog management library for Kandy I decided to follow that rule and not to pollute the standard Context class with a number of extension functions. Eventually, I added only two extension functions: create and show. Both of them construct an instance of DialogContext implicitly and let you use its dialog-specific API. Here’s an example of showing simple exit confirmation dialog:

Conclusion

Although I did my best to give simple examples and clearly explain the idea of the context in various ways and from various perspectives, a concise summary in points may still be helpful.

  • Context is a span surrounding statements and expressions
  • Context defines the set of actions you can take, i.e. methods to invoke, variables to use, etc.
  • The following, among others, create a context: a class, a method (or a function, a procedure, etc.), a block of code
  • Generally, all scopes have little contexts of their own
  • In some cases, you can use the idea of context to provide a compile-time validation of logic and data consistency
  • You can make use of contexts to keep an interface neat and simple by supplying only a minimal set of actions
  • A few, small contexts with clear responsibility are better than one, huge, contaminated context of the universe

Afterword

As always, many thanks for reaching the end of my article. I hope you didn’t get bored (too much?) but found something interesting and useful for yourself. If you liked it, consider clapping your hands 👏 and writing a comment. Any kind of feedback will be much appreciated (yes, including constructive criticism.)

If you’re an Android developer, you can also give Kandy a try. It’s a set of open-source libraries with the aim to make some of the overly complicated/verbose aspects of Android development, more friendly.

What’s next

--

--