216

This is going to be a very non-technical, soft question and I am not sure if this is the right platform. But I am a beginning CS student so I hope you guys tolerate it.

In the first semester we were introduced to OOP concepts like encapsulation, data hiding, modularity, inheritance and so on through Java and UML. (Java is my first programming language)

The way I understand it, OOP is a way of managing software complexity. But its principles are not new or unique, they are in a sense universal to all engineering fields.

For example a car is a very complex structure whose complexity is managed by a hierarchy of modular and encapsulated components with well-defined behaviors and interfaces.

But I do not understand the reason behind introducing a new programming paradigm. I think all the principles used for managing complexity can be realized by procedural programming languages. For example, for modularity we can just divide the program into many small programs that perform well-defined tasks whose code is contained in separate files. These programs would interact with each other through their well-defined input and output. The files may be protected (encrypted?) to achieve encapsulation. For code re-use we can just call those files whenever they are needed in new programs. Doesn't this capture all what OOP is or am I missing something very obvious?

I am not asking for a proof that OOP manages complexity. In my opinion it certainly does. But I think all the principles used to manage complexity like modularity, encapsulation, data hiding and so on can be very easily implemented by procedural languages. So why really OOP if we can manage complexity without it?

Robert Harvey
  • 200,592

16 Answers16

216

In the first semester we were introduced to OOP concepts like encapsulation, data hiding, modularity, inheritance and so on through Java and UML. (Java is my first programming language)

None of those are OOP concepts. They all exist outside of OO, independent of OO and many even were invented before OO.

So, if you think that that is what OO is all about, then your conclusion is right: you can do all of those in procedural languages, because they have nothing to do with OO.

For example, one of the seminal papers on Modularity is On the Criteria To Be Used in Decomposing Systems into Modules. There is no mention of OO in there. (It was written in 1972, by then OO was still an obscure niche, despite already being more than a decade old.)

While Data Abstraction is important in OO, it is more a consequence of the primary feature of OO (Messaging) than it is a defining feature. Also, it is very important to remember that there are different kinds of data abstraction. The two most common kinds of data abstraction in use today (if we ignore "no abstraction whatsoever", which is probably still used more than the other two combined), are Abstract Data Types and Objects. So, just by saying "Information Hiding", "Encapsulation", and "Data Abstraction", you have said nothing about OO, since OO is only one form of Data Abstraction, and the two are in fact fundamentally different:

  • With Abstract Data Types, the mechanism for abstraction is the type system; it is the type system that hides the implementation. (The type system need not necessarily be static.) With Objects, the implementation is hidden behind a procedural interface, which doesn't require types. (For example, it can be implemented with closures, as is done in ECMAScript.)
  • With Abstract Data Types, instances of different ADTs are encapsulated from each other, but instances of the same ADT can inspect and access each other's representation and private implementation. Objects are always encapsulated from everything. Only the object itself can inspect its own representation and access its own private implementation. No other object, not even other objects of the same type, other instances of the same class, other objects having the same prototype, clones of the object, or whatever can do that. None.

What this means, by the way, is that in Java, classes are not object-oriented. Two instances of the same class can access each other's representation and private implementation. Therefore, instances of classes are not objects, they are in fact ADT instances. Java interfaces, however, do provide object-oriented data abstraction. So, in other words: only instances of interfaces are objects in Java, instances of classes are not.

Basically, for types, you can only use interfaces. This means parameter types of methods and constructors, return types of methods, types of instance fields, static fields, and local fields, the argument to an instanceof operator or a cast operator, and type arguments for a generic type constructor must always be interfaces. A class may be used only directly after the new operator, nowhere else.

For example, for modularity we can just divide the program into many small programs that perform well-defined tasks whose code is contained in separate files. These programs would interact with each other through their well-defined input and output. The files may be protected (encrypted?) to achieve encapsulation. For code re-use we can just call those files whenever they are needed in new programs. Doesn't this capture all what OOP is or am I missing something very obvious?

What you describe is OO.

That is indeed a good way to think about OO. In fact, that's pretty much exactly what the original inventors of OO had in mind. (Alan Kay went one step further: he envisioned lots of little computers sending messages to each other over the network.) What you call "program" is usually called an "object" and instead of "call" we usually say "send a message".

Object Orientation is all about Messaging (aka dynamic dispatch). The term "Object Oriented" was coined by Dr. Alan Kay, the principal designer of Smalltalk, and he defines it like this:

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.

Let's break that down:

  • messaging ("virtual method dispatch", if you are not familiar with Smalltalk)
  • state-process should be
  • locally retained
  • protected
  • hidden
  • extreme late-binding of all things

Implementation-wise, messaging is a late-bound procedure call, and if procedure calls are late-bound, then you cannot know at design time what you are going to call, so you cannot make any assumptions about the concrete representation of state. So, really it is about messaging, late-binding is an implementation of messaging and encapsulation is a consequence of it.

He later on clarified that "The big idea is 'messaging'", and regrets having called it "object-oriented" instead of "message-oriented", because the term "object-oriented" puts the focus on the unimportant thing (objects) and distracts from what is really important (messaging):

Just a gentle reminder that I took some pains at the last OOPSLA to try to remind everyone that Smalltalk is not only NOT its syntax or the class library, it is not even about classes. I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea.

The big idea is "messaging" -- that is what the kernal of Smalltalk/Squeak is all about (and it's something that was never quite completed in our Xerox PARC phase). The Japanese have a small word -- ma -- for "that which is in between" -- perhaps the nearest English equivalent is "interstitial". The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Think of the internet -- to live, it (a) has to allow many different kinds of ideas and realizations that are beyond any single standard and (b) to allow varying degrees of safe interoperability between these ideas.

(Of course, today, most people don't even focus on objects but on classes, which is even more wrong.)

Messaging is fundamental to OO, both as metaphor and as a mechanism.

If you send someone a message, you don't know what they do with it. The only thing you can observe, is their response. You don't know whether they processed the message themselves (i.e. if the object has a method), if they forwarded the message to someone else (delegation / proxying), if they even understood it. That's what encapsulation is all about, that's what OO is all about. You cannot even distinguish a proxy from the real thing, as long as it responds how you expect it to.

A more "modern" term for "messaging" is "dynamic method dispatch" or "virtual method call", but that loses the metaphor and focuses on the mechanism.

So, there are two ways to look at Alan Kay's definition: if you look at it standing on its own, you might observe that messaging is basically a late-bound procedure call and late-binding implies encapsulation, so we can conclude that #1 and #2 are actually redundant, and OO is all about late-binding.

However, he later clarified that the important thing is messaging, and so we can look at it from a different angle: messaging is late-bound. Now, if messaging were the only thing possible, then #3 would trivially be true: if there is only one thing, and that thing is late-bound, then all things are late-bound. And once again, encapsulation follows from messaging.

Similar points are also made in On Understanding Data Abstraction, Revisited by William R. Cook and also his Proposal for Simplified, Modern Definitions of "Object" and "Object Oriented":

Dynamic dispatch of operations is the essential characteristic of objects. It means that the operation to be invoked is a dynamic property of the object itself. Operations cannot be identified statically, and there is no way in general to [know] exactly what operation will executed in response to a given request, except by running it. This is exactly the same as with first-class functions, which are always dynamically dispatched.

In Smalltalk-72, there weren't even any objects! There were only message streams that got parsed, rewritten and rerouted. First came methods (standard ways to parse and reroute the message streams), later came objects (groupings of methods that share some private state). Inheritance came much later, and classes were only introduced as a way to support inheritance. Had Kay's research group already known about prototypes, they probably would have never introduced classes in the first place.

Benjamin Pierce in Types and Programming Languages argues that the defining feature of Object-Orientation is Open Recursion.

So: according to Alan Kay, OO is all about messaging. According to William Cook, OO is all about dynamic method dispatch (which is really the same thing). According to Benjamin Pierce, OO is all about Open Recursion, which basically means that self-references are dynamically resolved (or at least that's a way to think about), or, in other words, messaging.

As you can see, the person who coined the term "OO" has a rather metaphysical view on objects, Cook has a rather pragmatic view, and Pierce a very rigorous mathematical view. But the important thing is: the philosopher, the pragmatist and the theoretician all agree! Messaging is the one pillar of OO. Period.

Note that there is no mention of inheritance here! Inheritance is not essential for OO. In general, most OO languages have some way of implementation re-use but that doesn't necessarily have to be inheritance. It could also be some form of delegation, for example. In fact, The Treaty of Orlando discusses delegation as an alternative to inheritance and how different forms of delegation and inheritance lead to different design points within the design space of object-oiented languages. (Note that actually even in languages that support inheritance, like Java, people are actually taught to avoid it, again indicating that it is not necessary for OO.)

Gerbrand
  • 239
Jörg W Mittag
  • 104,619
181

Let me try with a really low theory answer :)

What you are really asking is: Why include support for Object Orientation (OO) directly in the language when procedural languages can be used to design and write OO code?

And the answer is: To have a standard for how OO is expressed in the source code so you don't end up with 22 different implementations for the same abstraction.

For example, lets say I create a MagicButton and a MagicSlider which can be used in an user interface system. I need a way to group the methods which can be used with the MagicButton, the methods which can only be used with the MagicSlider, and the methods which can be used by both. These objects share some methods because they are both Magic gui objects.

I can do the grouping by naming functions in a special way MagicSlider_DoSomething ..., by including the methods in specific files named in a special way MagicSliderMethods.XXX, or I could find some other special way to do the same thing. If there is no standard way in the language to do it I will do it different from you, and differently from anyone else. This makes sharing code much more difficult.

Yes, late dispatch – virtual methods in OO languages – can be implemented in procedural languages, but there are so many different ways to implement it. Depending on who wrote the code you will end up with different implementations of OO inside the same program.

Think about the poor maintenance developer. This person must manage different object abstractions and different ways to call virtual methods depending on who wrote the original code.

Also: Having the abstractions in the language allows advanced code editors such as Eclipse to do a lot of static analysis on the code. For example Eclipse can offer up a list of all methods which can be used on an object, as well as auto implementation of empty "TODO methods". Eclispe knows exactly which methods your class must implement based on which classes you extend and which interfaces you implement. This would be almost impossible if there were not a language standard to do OO.

MTilsted
  • 1,466
67

But I think all the principles used to manage complexity like modularity, encapsulation, data hiding and so on can be very easily implemented by procedural languages.

When you say, "very easily" you're making a very bold statement. The way I read it is: "I don't see the difficulty, so it must not be very large." When phrased that way, it becomes clear that you're not asking "why do we need OO", you're asking "why aren't the difficulties that other programming paradigms encountered that lead to the invention of OO immediately apparent to me?"

An answer to that question is that many of these difficulties do not exist in the kinds of programs you're working on. You are not being asked to update 40-year old spaghetti code. You are not attempting to write a new display manager for an operating system. You are not debugging multithreaded distributed applications.

For many of the kinds of toy programs we CS students are tasked with writing, we could just as well be writing them in BASIC or assembly as Java or Python. That is because the inherent complexity of the tasks are so low, there is only one developer, there are no legacy interoperability issues, performance doesn't matter, and the code will likely only ever be run a handful of times on one machine.

Imagine taking a student driver and asking them to merge onto a busy street in rush hour, on a manual transmission with no synchromesh, heading up a steep hill. Disaster. Why? They are unable to manage the level of complexity required to simultaneously follow all of the rules that the task requires.

Now imagine the same student, same vehicle, driving at a walking pace in an empty parking lot. They are OK, because their level of skill is adequate to the task. There is no pressure, little risk, and they can take the individual subtasks of starting, clutching, shifting, accelerating, steering one at a time.

That student might ask why we have automatic transmissions, if a skilled driver can do all of these things simultaneously? The answer is that a skilled enough driver doesn't, in optimal conditions, need an automatic. But we're not all professional drivers in peak condition, and we typically want the convenience of having the car's designers take care of all that complexity for us.

A skilled, disciplined enough programmer can indeed create a functioning high-complexity system in C, or assembly. But we're not all Linus Torvalds. Nor should we have to be, to create useful software.

I personally have no interest in having to reinvent all the features of a modern language before I can even address the problem at hand. If I can take advantage of a language that includes solutions to already solved problems, why wouldn't I?

So I will turn your question around, and ask you, if languages provide convenient features like encapsulation, and polymorphism, why shouldn't we use them?

22

What you are describing is not OOP, it's abstraction. Abstraction is present in all modern models of design, even ones that aren't OOP. And OOP is a very specific kind of abstraction.

First, it's worth noting that there is no single definition of OOP, so there may be people who disagree with what I'm characterizing as OOP.

Secondly, it's important to remember that OOP was inspired by traditional models of design, so the similarities to car design is no coincidence.

However, here's some ways OOP is more nuanced than what you've said:

  • Encapsulation: this isn't just about having a set interface for a module (i.e. abstraction), it's about forbidding access beyond this interface. In Java, accessing a private variable is a compile error, whereas in your car design, you can (in some cases) use things in a way that's different from the intended interface.

  • Inheritance: This is really the thing that makes OOP unique. Once you've defined an interface, you can make multiple things implementing that interface, and you can do this in a heirarchical way, altering specific parts of their implementation, while inheriting all the previous parts, massively reducing code duplication.

    If you think in terms of the encapsulated components of a car, there's not really an equivalent to this. There's not a way for me to make a gear by taking a different gear and changing a specific part of its implementation. (At least I don't think so, I don't know much about cars).

  • Polymorphism: Once you've defined an interface, anything using that interface should be indistinguishable, from the point of view of what operations are available, and you shouldn't need to know what implementation is being used to use an interface. This is where subtyping and the Liskov Substitution Principle become important.

  • Coupling: A key aspect of OOP is that we closely relate things with the same operations, and spread out the different forms that they can have. Data are bundled with operations on that data. This means that it is very easy to add a new form of data (a new implementation), but very difficult to add a new operation to an interface (since you'd have to update each class that implements the interface). This is in contrast to Algebraic Data Types in functional languages, where it's very easy to add a new operation (you just write a function that deals with all the cases), but hard to add a new variant (since you need to add a new case to all your functions).

11

Do we really need OO languages to manage software complexity?

This depends on the meaning of the word, "need."

If "need" means requires, no we do not require it.

If "need" means "provides strong benefits", then I would say, "Yes," we desire it.

Big picture

OO languages bind functionality to data.

You can avoid this binding and write functions that pass around data values.

But then you'll probably wind up with constellations of data that go together, and you'll start passing around tuples, records, or dictionaries of data.

And really, that's all method calls are: partial functions on bound sets of data.

Feature by feature

Features of OOP:

  • Inheritance allows for code (mixins) and concept (Abstract Base Classes/interfaces) reuse - but you can get this by redecorating functions and variables in a sub-scope.
  • Encapsulation allows for information hiding so we can work at higher levels of abstraction - but you can do this with header-files, functions, and modules.
  • Polymorphism allows us to use arguments of different types so long as those arguments support the same interfaces - but we can do that with functions as well.

However, none of those things happens so easily as with an object oriented language with first class support of those features.

References

There are lots of critics of OOP.

However, studies seem to indicate that we get greater programmer productivity from code reuse through OOP. This is a controversial finding, and some researchers say they can't reproduce these productivity gains, given certain constraints. (source)

Conclusion

We don't "need" OOP. But in some cases the user wants OOP.

My understanding is that mature programmers can be quite productive in the object-oriented style. And when packages have core objects with simple interfaces that are easily understood, even new programmers can become quite productive quickly.

Aaron Hall
  • 6,003
11

I will try to be brief.

The core principle of OO is the combination of data and behavior in a single organizational unit (an object).

This is what allows us to control complexity and it was a pretty innovative concept when it emerged. Compare that to files on the one hand (pure data), programs that read and process those files on the other hand (pure logic) and output (pure data again).

Only once you have that package of data and logic together, modeling some real-world entity, you can start exchanging messages, create child classes, separate private from public data and behavior, implement polymorphic behavior, do all this OO-specific magic.

So, yes, OO is a big deal. And no, it is not just a bunch of old stuff with a fancy name.

Taking it all apart, looking at the elements and then saying "oh, well, there's nothing here I haven't seen before" is not recognizing the assembly that holds the innovation. The result is more than the sum of its parts.

Martin Maat
  • 18,652
8

There is no "official" definition of object oriented programming, and reasonable people disagree on what actually is defining quality of OO. Some say messaging, some say subtyping, some say inheritance, some say the bundling of data and behavior. That does not mean the term is meaningless, just that you shouldn't get too caught up in bickering about what real OO is.

Encapsulation and modularity are more fundamental principles of design, and should be applied in all programming paradigms. Proponents of OO does not claim that these properties can only be achieved with OO - only that OO is particularly well suited to achieving this. Of course the proponents of other paradigms like say functional programming claim the same for their paradigm. In practice many successful languages are multi-paradigm and the OO, functional etc. should be seen as tools rather than the "one true way".

I think all the principles used for managing complexity can be realized by procedural programming languages.

True, because in the end you can do anything in any programming language. It might just be easier in some languages than in others, since all languages have different strengths and weaknesses.

JacquesB
  • 61,955
  • 21
  • 135
  • 189
7

Something the other answers haven't mentioned: state.

You talk about OO as a tool for managing complexity. What's complexity? That's a fuzzy term. We all have this gestalt sense of what it means, but it's harder to pin it down. We could measure cyclomatic complexity, i.e. the number of run-time paths through the code, but I don't know that's what we're talking about when we use OO to manage complexity.

What I think we're talking about is state-related complexity.

There are two main ideas behind encapsulation. One of them, the hiding of implementation details, is pretty well-covered in the other answers. But another is hiding its run-time state. We don't muck around with objects' internal data; we pass messages (or call methods if you prefer implementation detail over concept as Jörg Mittag pointed out). Why?

People have already mentioned it's because you can't change the internal structure your data without changing the code the accesses it, and you want to do that in one place (the accessor method) instead of 300 places.

But it's also because it makes the code hard to reason about: procedural code (whether in a language that is procedural in nature or is simply written in that style) offers little help for imposing restrictions on the mutation of state. Anything can change at anytime from anywhere. Calling functions/methods may have spooky action-at-a-distance. Automated testing is more difficult, since the success of the tests is determined by the value of non-local variables that are widely accessed/accessible.

The other two large programming paradigms (OO and functional) offer interesting, but almost diametrically opposed solutions to the problem of state related complexity. In functional programming one tries to avoid it entirely: functions are generally pure, operations on data structures return copies rather than updating the original in place, etc.

OO on the other hand offers tools to deal with managing state (instead of tools for avoiding it). In addition to the language-level tools like access modifiers (protected/public/private), getters and setters, etc. there are also a number of related conventions like the Law of Demeter which advises against reaching through objects to get at other objects data.

Note that you don't need objects to do really any of this: you could have a closure that has inaccessible data and returns a data structure of functions to manipulate it. But isn't that an object? Doesn't that fit our conception of what an object is, intuitively? And if we have this concept, isn't it better to re-ify it in the language rather than (as other answers have said) relying on a combinatorial explosion of competing ad-hoc implementations?

Jared Smith
  • 1,935
5

Do we really need OO languages to manage software complexity?

No. But they can help in many situations.

I have used primarily a single OO language for decades, but most of my code is actually strictly pre-OO-style procedural. However, for anything involving a GUI, I use the language's vast OO library of built-in methods and objects, because it tremendously simplifies my code.

For example, a Windows application using the original low level Windows API to display a form, a button, and an edit field requires a lot of code, while instead using the libraries of objects that come with Visual Basic or C# or Delphi make the same program tiny and trivial. So, my OO code is usually relatively small and for the GUI, while my code that those objects invoke is typically much larger and usually not concerned with being OO (though it can vary depending on the problem I'm trying to solve).

I have seen OO programs that were overly complicated, relied on complicated esoteric rules about how the objects were implemented, and could have been much simpler if written without OO concepts. I have also seen the opposite: complex systems crying out to be reimplemented and simplified by using objects.

As you gain experience, you'll find different situations require different tools and solutions, and one size does not fit all.

3

As somebody who is involved in a very large project entirely written in C, I can definitely say that the answer is a clear "no".

Modularity is important. But modularity can be implemented in practically any decent language. For example, C supports modular compilation, header files and structure types. This is enough for 99% of the cases. Define a module for each new abstract data type you need, and define the functions for operating on the data type. Sometimes, you want performance and those functions are in the header file as inline functions, other times you will use standard functions. It is all invisible to the user which way is chosen.

Structures support composition. For example, you can have a locked hash table that consists of a mutex lock and a regular hash table. This is not object oriented programming; no subclassing is done. Composition is a tool that is much older than the idea of object oriented programming.

For the 1% of the cases where compilation level modularity is not enough, and you need runtime modularity, there is a thing called function pointers. They allow having individual implementations of a well-defined interface. Note that this is not object oriented programming in a non-object-oriented language. This is defining an interface and then implementing it. For example, subclassing is not used here.

Consider perhaps the most complex open source project there is. Namely, the Linux kernel. It is written entirely in the C language. It is done mainly by using the standard compilation level modularity tools including composition, and then occasionally whenever runtime modularity is needed, function pointers are used to define and implement an interface.

If you try to find an example of object oriented programming in the Linux kernel, I'm sure finding such example is very hard, unless you extend object oriented programming to include such standard tasks such as "defining an interface and then implementing it".

Note that even the C programming language supports object oriented programming if you really need it. For example, consider the GTK graphical user interface toolkit. It is actually object oriented, albeit written in a non-object-oriented language. So, this shows that the idea that you need an "object oriented language" is deeply flawed. There is nothing an object oriented language can do that another kind of language cannot do. Furthermore, if you're an expert programmer, you know how to write object oriented code in any language very easily. It is not a burden to use C, for example.

So, the conclusions are that object oriented languages are probably useful only for novice programmers who fail to understand how the concept is actually implemented. However, I wouldn't want to be near any project where the programmers are such novice programmers.

juhist
  • 2,579
  • 12
  • 14
2

The reason for introducing programming paradigms, including object-oriented methods, is to make it easier to make more sophisticated and powerful programs. In the August 1981 issue of Byte Magazine, Daniel Ingalls, one of the key creators of Smalltalk, defined "object oriented" as involving the following capabilities:

  • automatic storage management
  • ability to exchange messages
  • a uniform metaphor that applies to all operations of the language
  • no component depends on the internals of another component (modularity)
  • program defines only behavior of objects, not their representation (polymorphism)
  • each component should appear in only one place (factoring)
  • the use of a virtual machine which is hardware independent
  • every user-accessible component should be available for observation and control (reactive principle)
  • there should be no overall controller (no operating system)

These were the principles Ingalls identified as being the driving design considerations for SmallTalk-80 as developed by Xerox Parc Research. In the aforementioned magazine article you can read a detailed description of each of the these principles and how they contribute to the object-oriented paradigm according to Ingalls.

All of these principles can be applied using any Turing complete language, whether it be procedural, assembly language or whatever. These are design principles, not a language specification. An object-oriented language is intended to make it easier to use these principles when creating software.

For example, to take the first of Ingall's principles (automatic storage management), anyone can write their own automatic storage management system in a procedural language, but it would be a lot of work to do so. When using a language such as SmallTalk or Java that has automatic storage management built in, the programmer does not have to do as much work managing memory. The tradeoff is that the programmer gets less control over the way memory is used. So, there is a benefit and a drawback. The idea of a design paradigm like object-oriented programming is that the benefits of the paradigm will outweigh the disadvantages for at least some programmers.

0

The one thing to remember is this:
OOP is not about language features; it is about the way you structure your code.

OOP is a way of thinking, and of designing the architecture of your code, and it can be done in just about any language. This especially includes those low-level, non-OO languages, which are called assembler and C. You can do perfectly object-oriented programming in assembler, and the Linux kernel, which is written in C, is quite object-oriented in many aspects.

That said, OO features in a language greatly reduce the amount of boilerplate code that you need to write to achieve the desired results. Where you need to explicitly define a virtual function table and fill it with the appropriate function pointers in C, you just do nothing in Java, and you are done. OO languages simply remove all that enabling cruft from the source code, hiding it behind nice, language-level abstractions (like classes, methods, members, base classes, implicit constructor/destructor calls, etc.).

So, no, we don't need OO languages to do OOP. It's just that OOP is so much easier to do with a decent OO language.

0

One way of managing software complexity is to separate the framework from the desired actions entirely using a Domain Specific Language. This means that the level of programming code is distinct from the level at which desired results are configured - a completely different language or system. When this is done properly, the conventional code essentially becomes a library, and the user or other person creating the desired results plugs things together with a scripting language or visual design tool, such as a report generator.

To work, this requires drawing a strict boundary around what operations will be possible and how they link up (script language or visual design, like a form construction tool). Metadata is an important way of abstracting out the run-time configuration from the coding details, making it possible for a system to support a wide range of desired results. If the boundaries are laid out and held to (not accepting every request for extension that comes along) you can have a long-lasting and robust system that works for people, without them needing to be programmers to accomplish what they want.

Martin Fowler has written a book about this, and the technique is almost as old as programming itself. You could almost say that all programming languages are Domain Specific Languages, and so the idea is endemic, overlooked because it is so obvious. But you can still create your own scripting or visual design tools to make your life easier. Sometimes generalizing a problem makes it far easier to solve!

0

This is a very good question and I feel the answers given here have not done justice, so I will go ahead and add my thoughts.

The aim is - Manage Software Complexity. The aim is not "use OO language".

The is no 'reason' behind introducing a new paradigm. It is something that happened naturally as coding became more mature. It makes more sense to write code where we add a coach at the end of the train (the train being modeled using a linked list) rather than adding a new node to the end of the linked list.


Coding in terms of real world entities is simply the obvious and correct way to code when we are coding about the real world entities.


A computer can work with adding a node to the end of linked list as easily as it can work with adding an extra coach to the end of the train. But for humans it is easier to work with the train and coach than with linked list and nodes even though when we go a level deep, we find the train being modeled by means of a linked list.

Protecting or encrypting the files cannot achieve encapsulation. The opposite of encryption is decryption. The opposite of encapsulation is Decapsulation which means Decomposition of structures and classes in programming languages to achieve better performance. The performance gained from reducing memory traffic and avoiding OOP rules checks.

Hence you can write code that is both encrypted and well encapsulated because these two are different concepts.

Encapsulation helps in managing the complexity by virtue of it being close to the reality.

Therefore, program in objects because, it is easier for you to code and it is faster for you and everyone else to understand.

-2

The biggest reason is that, as a program gets more complex, you need to make some parts of it invisible from other parts, or the complexity of the app and the number of functions will make your brain dribble out of your ears.

Let's imagine a system of 100 classes, each with about 20 operations that can be performed on them; that's 2,000 functions. However, of those, maybe only 500 are complete operations like 'Save' and 'Delete', while 1500 are internal functions which perform a little bit of maintenance, or have some utility role. Consider;

// intentionally in a non-specific language!

setName(person, name) {
    nameParts = splitPersonName(name);
    person.firstName = nameParts[0];
    person.lastName = nameParts[1];
    person.modified = true;
}

splitPersonName(name) {
    var result = [];
    result.add(name.substring(0, name.indexOf(" ")));
    result.add(name.substring(name.indexOf(" ") + 1));
    return result;
}

So SetName is a function people should be doing to a person, but SplitPersonName is a utility function used by the person.

Straight procedural programming makes no distinction between these two operations. That means your 2,000 functional all vie for your attention. However, if we could mark these functions as 'available to everyone who has a person record' and 'used only as a utility function inside the person record' then our attention is now 500 'available to everyone' functions, and 15 'utility' functions for the class you're editing.

That's what public and private do;

public class Person {
    public void setName(...) {...}
    private string[] splitPersonName(...) { ...}
}
user62575
  • 285
-2

Object oriented programming is more than just modules + encapsulation. As you say, it is possible to use modules + encapsulation in a non-object-oriented (procedural) language. OOP involves more than just that: it involves objects and methods. So, no, that doesn't capture OOP. See, e.g., https://en.wikipedia.org/wiki/Object-oriented_programming or a good textbook's introduction to OOP.

D.W.
  • 466