
The interface can be considered a kind of contract between the system and the external environment. In the framework of the computer program "system" - the function or module under consideration, and the "environment" is the rest of the project. The interface formally describes what data can be transferred between the system and the environment. A "implementation" can be described as "system minus interface." In languages like Haskell, interfaces can be very specific. And in languages like Python, by contrast, they are very ordinary. The selected interface type can affect the size of the technical debt created and the productivity of the programmer. How to calculate it is written below. A method for evaluating and comparing different interfaces will also be proposed. Based on these comparisons, you can see for yourself how to use a language or software tool.
The most important concept in software development is the
interface concept. This article is not about Java interfaces, but about interfaces in software design. And to a lesser extent - about the interfaces in the outside world. Of course, many other important concepts are used in software development, but I believe that most of them somehow depend on the importance of the interface.
What is an interface?
Most of us are familiar with two brief formulations:
')
The interface is a contract between the system and the external environment.
The interface is the pairing of the system with the external environment.= ∩

The definition with conjugation is better suited if the system is a physical object. Both definitions are very abstract, so let's look at them on the example of typing on the keyboard:

Here the system is a laptop, the environment is the hands (and also the paws of a cat who has climbed onto the keyboard). Consequently, the interface should be any part of the interaction between the hands and the laptop, which cannot be attributed only to one of the parties, but only to both. Usually we think about the hands and the keyboard apart, so that the exact boundaries of the interface in this case - the subject of a philosophical dispute. It is up to you whether it will be the keyboard as a whole or individual atoms interacting with each other when the fingers and keys come in contact.
It will probably surprise you how this example correlates with the definition of an interface as a contract. In this case, the contract implies an agreement that we once spent enough effort when we memorized the key layout and accumulated muscle memory. A number of nuances are associated with the contract. For example, pressing and holding a key has a different meaning compared to just pressing it once.
These are all curious philosophical arguments, but how do they relate to writing software? Well, let's start with the fact that interfaces in programming surround you from all sides, even if you do not pay attention to it. For example, if you are programming in Java, you explicitly name interfaces depending on their purpose. And in other languages they are also present. Let's look at an example of the interface of the
add_numbers
function:
unsigned int add_numbers(unsigned int, unsigned int); void other_function(void){ add_numbers(3,4); } unsigned int add_numbers(unsigned int a, unsigned int b){ return a + b; } int main(void){ add_numbers(9,99); return 0; }
We apply the same method of color differentiation of
pants to describe the environment, the
add_numbers
system and the interface:




The “system” considered here consists of the
add_numbers
function. If you say that the main method, the
other_function
, can be considered as a separate system, then you will be right. But for simplicity, we consider the
add_numbers
function
add_numbers
isolated system. It is also advisable to consider part of the interface to access
add_numbers
.
As you can see, a fourth concept has been added here: “implementation”. It is quite difficult to discuss the topic of interfaces without taking into account specific implementations. Let's define this term:
An implementation is a system minus interface.Implementation = System ∖ Interface
Implementation = System ∖ (System ∩ Environment)

I must confess that I have never come across such a definition of implementation. But this is an inevitable extension of the interface definition set, which has several advantages. If you are a poor student and are preparing for an exam, then surely your teacher has never heard of such a definition. I would not be surprised if it would contradict any taxonomy of object-oriented programming. But even in this case, I'm not going to change it. Let better OOP fans rewrite their notes in accordance with my definition.
It, in turn, leads us to the following logical conclusion: when we talk about the interfaces of a physical system, we usually imagine the “realization” of this system as a single physical object. After all, it would be strange to consider the "real" implementation without taking into account buttons, displays or other components. And it pushes us to consider the interface more as a “convention”, rather than a collection of physical objects. That is, in the form of a set of promises, guarantees, or something like ... a
contract between the system and the environment .
Interface as a contract
If we consider the interface of the
add_numbers
function as a contract, then the guarantees will be as follows:
- The
add_numbers
function exists. add_numbers
has only two parameters, each of which is an unsigned int
.add_numbers
returns only one unsigned int
.
The interface of this function tells us nothing:
- about interrupting the execution of
add_numbers
; - about the asymptotic complexity of runtime
add_numbers
; - about the amount of free memory required to run
add_numbers
; - about a specific unsigned
int
implementation; - about side effects (memory allocation, modification of global variables).
The
add_numbers
interface described above is known as the
prototype
function. In previous versions of K & R C, a weaker form of interface description was used:
unsigned int add_numbers();
Defining an interface as a contract is very convenient for programming. After all, the majority of programmer tasks consist in defining and querying sets of axioms. Initial and final conditions provide some properties or behavior. Before the two parties establish business relations with each other, they prepare a contract. It sets out the final result, the amount and terms of payment. The terms of early termination, reimbursement and costs are also stipulated in advance. If the contract is violated, the situation is settled by the court or arbitration. But if you forgot to specify something in the contract, then surprises may arise.
With computer programs everything is the same. Modules and functions say what they need and (sometimes) what they will give in return. Violation of this contract will lead to a compilation error, to a runtime error, to a failure of the application, system, code quality control measures and reprimand from the manual. I would even say that the definition of an interface as a contract is not metaphorical. It uses the same principles as in the commercial contract, although it is not so detailed.
Patents, copyrights and interfaces
I will not give you legal advice. Perhaps, something from what I have said will even contradict the laws. All of the following is only the personal opinion of the author.
So, I tend to
literally see the interface as a “commercial contract” between two entities. I emphasize - I do not think this is a metaphor. I especially address this interpretation to computer scientists and copyright advocates.
Should I patent the interface? Given its definition as a contract between the system and the environment, I believe that the use of patents would be a mistake. And, apparently, the existing case law supports my position. But keep in mind that the word "interface" is used very widely, and often not at all in the sense that I described above.
Should the interface be protected by copyright? Again, considering the “contractual” nature, I believe that the object of copyright should be the “source code” of the interface. At the same time, copyrights should not apply to those aspects of the interfaces that make them so special. It is enough to protect the source code or the handwritten image, but not guarantees or limitations. If the guarantees or restrictions of the interface become inseparable from any part of its code, then these parts should be deprived of their rights of protection.
I propose a simple test that allows you to assess whether something needs to be protected by copyright.
If you would like to protect a set of attributes, including any components from a third party, in any way used by the interface, you can always create a suitable replacement. The replacement implements the same interface and is successfully used in software from a third party, without any modifications of this software itself, and also without violating any copyright. If any replacement would violate the copyright, or imply third-party software modification, or degrade the functionality, then the set of attributes is too aggressive and should be reduced.I believe that with the help of this test it is advisable to check for patentability. Please note: the purpose of the test is solely to determine the
inappropriateness of protection by copyright or patent. It will not help in deciding what
should be protected. In addition, this test is just my opinion, not a regulatory act or law.
I also want to note that any criterion considered as part of the interface in one language may not be such in another language. For example, in Java, the function declaration order does not affect the execution of the program. And if you accidentally say that the order of the functions in the file does not matter, then this will be an error with respect to the Python program:
def foo(): print("asdf") def foo(abc): print(abc) foo("lol")
All this talk about the laws reminded me of the
Oracle v .
Google case. From the link below you can find interesting details for developers, so I will rely on them in my analysis. Considering all aspects, I see no reason to disagree with the decision of the case in favor of Oracle. I can’t say that I support them unconditionally, because not many details of the proceedings are available to us.
I think many people were worried that a precedent would be created that would allow to protect interface elements with a patent or copyright. Just that case at which my test would not be passed. The district court decided: "The structure, sequence and architecture of the API may be copyrighted." I don’t think this is a problem, since “structure, sequence and architecture”, by its definition, will completely pass my test. I will cite a couple of excerpts from the article at the link above:
“The district court concluded that" there is only one way of writing "declarations to interact with Java. If so, the use of identical ads is not subject to copyright protection. Google does not dispute the fact that they could write their own APIs for accessing Java, with the exception of three. ” Finally, "Google admitted that they literally copied the ads."I think the court made the right decision, concluding that the unique properties of the interface should not be protected. In addition, Google recognized the "verbatim" copying. If by this is meant copying, including all spaces and spelling errors in the comments, then I consider this a violation of rights. Even if the interface cannot be protected, this should not interfere with the protection of individual creative expression.
I know about this litigation only from open network sources, but, apparently, Google completely copied the original Java code, including interfaces. It seems that they themselves believed that they needed to license their use of Java, since this was the subject of negotiations on licensing agreements with Sun even before 2010. But these agreements failed after Sun was acquired by Oracle. Nevertheless, Google continued to use "verbatim" copies of the code, which clearly did not benefit her in the trial. I suspect that their lawyers knew about the weakness of their position, so they chose a defense strategy based on the legal requirement of non-proliferation of copyright on interfaces. We hoped to win the case by presenting the interface as source code and combining it with a more philosophical concept.
What is a "module" or "abstraction"?
When the word "module" in my head appears the title picture of the post. This illustration well demonstrates the importance of the boundaries of the module and its interaction with the environment. The cube interface severely restricts the interaction of the external environment with the contents of the cube. You will not be able to bypass the interface, so you have to follow the “rules of the game” imposed on them. Finally, there is nothing inside the cube, but this is unimportant: what matters is not its contents, but the interface.
Another example: the structure of the cell membrane. The various components ensure that only necessary substances pass through the membrane and only when it is needed.

In the context of this article, I will use the terms “modules” and “abstractions” as synonyms. Of course, the dictionary doesn’t agree with me, and even in different programming languages these terms have different meanings. But in this case, I am only interested in the fact that both of these entities can be considered as a system, as it is understood in this article. That is, abstractions and modules can consist of an interface and an implementation.
You can consider a separate function as a module in the C language, a “module” in Python, a class or a package in Java. Anything, if only it had an external interface and a "hidden" implementation. Moreover, the “secrecy” can be a consequence of the rules of the language or even the decision of the programmer.
Leaky abstractions
As far as I know,
Joel Spolsky put forward the idea of
holey abstractions . There are some good examples in his essay, but I would like to give my own. In programming, the concept of a "map" is very common: a representation of a data structure consisting of pairs of keys and values. An important limitation: the card ensures that all keys must be unique. Attempting to write a new value for an existing key will result in an error or overwrite the previous value. The bottom line is that keys should not be duplicated. Most often, programmers are required to sort through all these keys. And since cards cannot guarantee a specific key sorting order, sometimes you have to ask yourself, in what order will they be after the search? This is due to the fact that the interface of the card does not guarantee sorting. And although it is believed that it does not matter, but in practice I still want to sort. So it is necessary for more efficient organization of data, for example to facilitate the verification of existing keys.
Enumerating the sorted data can give a completely different result compared to iterating random data. Suppose you need to find the minimum value in the list:
min = null; list = map.getMapKeys(); for (item in list){ if ( min == null ){ min = item }else if (item < min){ min = min; } }
The
else if
branch will never be executed if the data is sorted in ascending order. Even if you start checking from a random place in the list, the program will never encounter this line. And this is a huge problem, because if you change the map implementation and it does not return sorted keys, your code will unexpectedly be executed on a branch with a bug. And by that moment you will completely forget about this code and the bomb hidden inside it.
I want to offer my own definition of abstraction leaks.
Abstraction leak is a situation where the implementation can affect the environment in a way that was not provided for by the interface.According to this definition,
almost every abstraction is full of holes. After all, the description in the interface of all types of influence on the environment makes sense only in the most rigorous mathematical systems. As for the physical systems, you may recall
Gödel’s incompleteness theorem .
The idea of being full of holes in most abstractions is not unreasonable. This was also implied by Joel Spolsky in his “The Law of Leaky Abstractions”:
"All non-trivial abstractions are leaky to a certain extent."Since all abstractions are full of holes, what should we talk about? Problems arise only when a part of the environment begins to rely on one of the unintended ways that the system influences the environment. It is about such leaks and they all say.
This leads to far-reaching consequences, not only in terms of common bugs, but also in the area of security. With the physical systems in which there are leaks in the external environment that compromise security, the term "
attack on third-party channels " is associated. Combined with the statement that all abstractions are leaky, this leads us to the conclusion:
Every physical implementation of a cryptosystem is vulnerable to third-party attacks.Given all the above, this idea can be extended not only to the physical, but also to the emulated implementation.
Interface evaluation and comparison
As we have already seen above, in C interfaces, things like the type of the return value and the number of parameters that can be passed to the function are specified. What about Python? I use the term "interface" in accordance with the context of the article, that is, in a broader sense compared to what is written in books about "interfaces" in Python.
def add_numbers(a,b): return a + b print(add_numbers(3,1)) print(add_numbers("abc","def"))
In this language, we need to formalize the interface types of the function. This simplifies the definition and function call, since less information needs to be processed. On the other hand, there are fewer restrictions on which it is possible to check over to find errors over time.
I think we need to say something about the evaluation and comparison of various characteristics of the interface in terms of methods of transmitting information. You can evaluate both a specific interface and a set of all interfaces that can be implemented in a given language. Let us recall our example with
add_numbers
and estimate how much information we can pass through the interface and bypassing it, using abstraction leaks.
Through interface | Bypassing the interface |
Description of the characteristic | Number of possible states | Description of the characteristic | Number of possible states |
Parameter type 1 | 1 (unsigned int) | Global variable states | (number of global variables) * (number of states of global variables) |
Parameter type 2 | 1 (unsigned int) | File system | Number of file system states |
Return type | 1 (unsigned int) | CPU time | Not limited |
Parameter value 1 | 2 ^ (number of bits in unsigned int) | Heap state | Number of heap states |
Parameter 2 value | 2 ^ (number of bits in unsigned int) | A lot others... | ... |
Return value | 2 ^ (number of bits in unsigned int) | |
And there are a number of things that can communicate with
add_numbers
via the Python interface.
Information transfer via Python interface | Passing Information Bypassing the Python Interface |
Description of the characteristic | Number of possible states | Description of the characteristic | - |
1 | | | - |
2 | | | |
| | | - |
1 | | | ... |
2 | | ... | (- ) * (- ) |
Return value | | |
, Haskell:
add_numbers :: Int > Int -> Int add_numbers 3 4 = 7 main = print (add_numbers 3 4)
,
add_numbers
:
Haskell | Haskell |
| - | | - |
1 | 1 (Int) | | |
2 | 1 (Int) | / | |
| 1 (Int) | ... | ... |
1 | 1 ( 3) | |
2 | 1 ( 4) |
Return value | 2^30[ 1 ] |
:
:
, :

GUI | GUI |
| - | | - |
1 | - , 1 * - | UI | |
2 | - , 2 * - | | - , 2 |
1 | - , 1 | UI | ... |
2 | - , 2 | |
| |
| - |
, GUI | - , GUI |
cd
:
, . ( ) ( ), , . . , «OK» «Cancel» 1 .
, .
, . :
. :
(leaky interface) — , .
(specific interface) — .—
- , .
«» «» , , , — .

, - , , . : . .
, , . «» , -
. ,
.
:
- , - , .- , (1). , (1), . (N^2). , , , N^2.

, . - , . - , . — , , .
, (N^2), , (N). , : . 20 , , , , . , . , , — .
?
, :
, ,
! . 100 , , GUI. GUI, - , , . … .
, , . , . , . GUI . , . , .
, , GUI — . , . ,
. , , .
, , Haskell Java. , . .
?
« », , . , , , , « ».
« », , : . — , ,
. , MVP . , , .
« », . , . , - ( ).
- , Twitter Ruby on Rails, . Twitter Scala. - , Scala. . Twitter' , . , . , , , . – , . Twitter' , . , , , : « , , ». - , , , . , «» , .
Python?
, , . , «» «» , .
, Python , , . Python .
Python . , .
Java/C++?
, . Java ++ , Python Ruby. , , ( Haskell), Java ++ , . , . , , .
- , : ,
. , ! , , :
- .
- «» Java.
- .
- .
- (.h) C/C++.
- RESTful API.
- URL.
- «» «».
- (DDL).
- And much more.
Conclusion
, , . , , .