Differences between Monolithic Architecture and SOA - oop

I confused these two architecture's differences.
Generally, Monolithic Architecture refers to different components of an application being combined into a single business logic.
And, Service Oriented Architecture refers to an application composed of discrete and loosely coupled software agents that perform a required function.
But I learned, OOP and design-pattern aim "One function should have One responsibility" and "Decrease dependencies to increase reuse of function".
So my question is :
1. Do monolithic architecture follow OOP?
2. Differences between these two architecture.

1. Do monolithic architecture follow OOP?
Good ones do. Yes. It would be even more of a spaghetti code mess if it was procedural or much harder to write if it was functional. In all the pro companies I've worked for they all had OOP and frameworks like MVP they also incorporate. In my experience supporting companies with problem products, they tended to be a mess. Really boated, little reuse, if one 1MB thing needed to scale the only way to do it was scale the entire 100MB solution.
2. Differences between these two architecture.
Service Orientated Architecture IMO is taking the view each function can be an API, its service orientated. Object Orientated Programming has a few tenants, Polymorphic, Reusable, Encapsulated (and Abstract), it's a style of programming, almost opposite to procedural programming etc.
When you design a service, let's say it's a Weather app that tells temp and also does predictions. You will want to have an abstract generic Weather class, make it support Celsius and Fahrenheit implementations and you can get some polymorphism, or perhaps add an Interface to support different locations or altitude's, and use really generic function names that sound abstract like GetTemp (with function overloads by City, State, Altitude) to encapsulate it in the Weather class.
So here you design it with the Service Orientation in mind and a solid OOP assembly.
"One function should have One responsibility" and "Decrease dependencies to increase reuse of function".
For the second service to predict temp's that will make some calculations and take time to compute so we will want to isolate it, so we can scale it independently. You can do this by using a different project and instead of referencing each other you put in Messaging technology (SQS, RabbitMQ, etc) so they are loosely coupled.
Note: We can simply cache the static GetTemp results in the other project to easily scale that part of the system.

Related

difference between system design and object oriented design

can someone please explain the difference between system design and object oriented design?
Object oriented design involves object modeling and uses object oriented concepts such as Abstraction, Encapsulation, Decomposition and Generalization. Both of the design involves Architectural design and conceptual design.
Is one of the design paradigm subset of other?
System design is the designing the software/application as a whole [high level] that may include analysis, modelling, architecture, Components, Infrastructure etc. whereas the objected-oriented design is the set of defined rules/concepts to implement the functionalities within a software.
Take an analogy, a football game.
So the System design involves the design of football ground, goal poles, grass on the ground, location of the ground, length/breadth of the ground, putting line marks on the ground, scoreboard, defining the playing teams, number of players to play etc.
Now, take object-oriented design: how the games need to be played is defined by a set of rules that need to be followed. Thus the players need to play the game within the defined rules. So the more the player knows those rules the better they can play the game without making fouls. Similarly, the rules for the object-oriented concepts are inheritance, composition, abstraction, encapsulation. Thus the better we know these concepts the better design we can make.
#Prashant, hope it explains a bit
Let's say you want to design an online shopping web Application (like amazon.com). So before making that web application you have to think of :
load balancing to handle the user requests,
database whether to use SQL or NOSQL,
whether to use cache like Redis or not,
making microservices for the different tasks ( like notification service, order processing service etc.)
monitoring your web application (like memory, cpu etc.),
logging (say in sumoLogic).
CI/CD
So all these will fall under system design as they are required for any system to work.
Now once you finalized all these things and went to implement (writing code) any part of the system then you can follow the Object-oriented design to make classes, interfaces etc.
For example, you started implementing the notification microservice ( say in Java), so now you have to design classes, interfaces etc., and for this, you can use the object-oriented design principles like SOLID.
So we can say that object-oriented design is a part of system design which comes into picture when we start working on the actual implementation for any part of the system.
System in System Theory can be everything. (Facets of Systems Science, George Klir, 1991) System is on TOP of TREE, Superclass of other categories.
In overall, System Development included 2 major phases:
1- System Analysis: including Planning, requirements, analysis and etc. These items related to specific methodology in system theory.
2- System Design: including design, implementation, test, deploy, maintenance and etc.
As I said, System can be everything. For example:
Mechanical systems, Psychological systems, Social systems, Aircraft Systems and so on. Each category may have detailed and specific analysis and design steps based on mentioned 2 major phases.
In computer world, Software Systems is one of System categories.
Each software Analysis and Design method is based on mentioned 2 major phases too.
Additionally, In Software Systems, we have some paradigms to analysis and design like:
Structural/Process Centered
Data Centered
Object Oriented
Service Oriented
and etc.
Each of them has it's own Analysis and Design Steps. These steps are based on 2 major phases as well. But in details, they have some differences.
To sum up, Systems Analysis and Design is a big picture to all other type of systems. Learning System Analysis and Design helps to understand all other systems analysis and design and specially helps to compare and evaluate them.
Objects are parts of a system. You can think Object Oriented Design is a part of System Design. You can design a system in high level (with overview) or in low level (with details). It will highlight
Infrastructure
Data flow management
Services
Cache management
Request/response management etc
When doing object oriented design you can think that you have to use some objects and making relations among them. But before making object you need to design some classes. So actually OOD (object oriented design) is
Designing class diagram (optional)
Making some classes
Making relations among classes
Using classes for creating objects
Implementing the purpose (basic functions and logics) etc

Difference between Programming Paradigm, Design Pattern and Application Architecture?

I'm from a non-programming background and have often come across the terms like Programming Paradigm, Design Pattern and Application Architecture. Although I think I have a vague understanding of what these terms mean, I'd appreciate if someone could clarify what each is, how it is different from the other and how these concepts apply to Objective C.
Programming Paradigm: Something like "Functional Programming", "Procedural Programming", and "Object Oriented Programming". The programming paradigm and the languages that use them inform how the code gets written. For example, in Object Oriented programming the code is divided up into classes (sometimes a language feature, sometimes not (e.g. javascript)), and typically supports inheritance and some type of polymorphism. The programmer creates the classes, and then instances of the classes (i.e. the objects) to carry out the operation of the program. In functional languages, the state changes on the computer are very heavily controlled by the language itself. Functions are first class objects, although not all languages where functions are first class objects are functional programming language (this topic is one of good debate). Code written with a functional languages involves lots of nested functions, almost every step of the program is new function invocation. For procedural programming, C programs and bash scripting are good examples, you just say do step 1, do step 2, etc, without creating classes and whatnot.
Design Pattern: A design pattern is a useful abstraction that can be implemented in any language. It is a "pattern" for doing things. Like if you have a bunch of steps you want to implement, you might use the 'composite' and 'command' patterns so make your implementation more generic. Think of a pattern as an established template for solving a common coding task in a generic way.
Application Architecture: Takes into consideration how you build a system to do stuff. So, for a web application, the architecture might involve x number of gateways behind a load balancer, that asynchronously feed queues. Messages are picked up by y processes running on z machines, with 1 primary db and a backup slave. Application architecture involves choosing the platform, languages, frameworks used. This is different than software architecture, which speaks more to how to actually implement the program given the software stack.
Some quick definitions,
Application Architecture describes the overall architecture of the software. For instance a web-based programs typically use a layered architecture where functionality is divided to several layers, such as user interface (html generation, handling commands from users), business logic (rules how the functions of the software are executed) and database (for persistent data). In contrast, a data processing application could use a so-called pipes and filters architecture, where a piece of data passes through a pipeline where different modules act on the data.
Design Patterns are a much lower level tool, providing proven models on how to organize code to gain specific functionality while not compromising the overall structure. Easy examples might include a Singleton (how to guarantee the existence of a single instance of a code) or a Facade (how to provide a simple external view to a more complex system).
On the other hand paradigms are the other extreme, guiding the principles on how code is actually laid out, and they each require quite different mindsets to apply. For instance, procedural programming is mainly concerned about dividing the program logic into functions and bundling those functions into modules. Object-oriented programming aims to encapsulate the data and the operations that manipulate the data into objects. Functional programming emphasizes the use of functions instead of separate statements following one another, avoiding side-effects and state changes.
Objective-C is mostly an object-oriented extension to C, design patterns and architecture are not language-specific constructs.
A programming paradigm is a fundamental style of computer programming.
Software Design Pattern - are best practice solutions to common software design problem. There are many design patterns for common problems. To learn more about design patterns you can read some books from this list 5 Best Books for Learning Design Patterns
Application Architecture - Applications Architecture is the science and art of ensuring the suite of applications being used by an organization to create the composite application is scalable, reliable, available and manageable.
I guess any of these terms would apply to all programming languages. Design patterns exists in all programming languages.
These are logical terms defined to create higher level of abstraction.
Hope this helps
Think of the vernacular interpretation of those terms (i.e., outside of the field computer science).
Paradigms are all-encompassing views of computation that affect not only what kinds of things you can do, but even what kinds of thoughts you can have; functional programming is an example of a programming paradigm.
Patterns are simply well-established programming tricks, codified in some semi-formal manner.
Application architecture is a broad term describing how complex applications are organised.
Objective-C primarily adds elements of the OO paradigm to the imperative language, C. Patterns and architecture are largely orthogonal to the language.
Simple English words
A paradigm is a way of thinking when programming, where first class concepts are used to organize the software. Ex oop use classes as first class citizens, functional or lambda calculus use functions and their compositions, aspect uses aspects of a system .... And so on. When thinking a solution the first thing that comes to your mind are the first class citizens. The objective is to organize the solution into software components.
A design pattern is a common successful use of software components.
An application architecture is a set of design patterns put together in order to realize use case scdnarios.
Paradigm: a style or approach to programming. For example, In OOP, we use the concept of objects, classes to overall program. These objects contain data & behaviours & we connect them logically to complete the task.
Design Patterns: tried or tested solution, moreover reusable solutions, to the problem we encounter while everyday programming. For example, if we approach OOP paradigm, there are no. of patterns to help us solve specific problem.

Significant Challengers to OOP

From what I understand, OOP is the most commonly used paradigm for large scale projects. I also know that some smaller subsets of big systems use other paradigms (e.g. SQL, which is declarative), and I also realize that at lower levels of computing OOP isn't really feasible. But it seems to me that usually the pieces of higher level solutions are almost always put together in a OOP fashion.
Are there any scenarios where a truly non-OOP paradigm is actually a better choice for a largescale solution? Or is that unheard of these days?
I've wondered this ever since I've started studying CS; it's easy to get the feeling that OOP is some nirvana of programming that will never be surpassed.
In my opinion, the reason OOP is used so widely isn't so much that it's the right tool for the job. I think it's more that a solution can be described to the customer in a way that they understand.
A CAR is a VEHICLE that has an ENGINE. That's programming and real world all in one!
It's hard to comprehend anything that can fit the programming and real world quite so elegantly.
Linux is a large-scale project that's very much not OOP. And it wouldn't have a lot to gain from it either.
I think OOP has a good ring to it, because it has associated itself with good programming practices like encapsulation, data hiding, code reuse, modularity et.c. But these virtues are by no means unique to OOP.
You might have a look at Erlang, written by Joe Armstrong.
Wikipedia:
"Erlang is a general-purpose
concurrent programming language and
runtime system. The sequential subset
of Erlang is a functional language,
with strict evaluation, single
assignment, and dynamic typing."
Joe Armstrong:
“Because the problem with
object-oriented languages is they’ve
got all this implicit environment that
they carry around with them. You
wanted a banana but what you got was a
gorilla holding the banana and the
entire jungle.”
The promise of OOP was code reuse and easier maintenance. I am not sure it delivered. I see things such as dot net as being much the same as the C libraries we used to get fro various vendors. You can call that code reuse if you want. As for maintenance bad code is bad code. OOP did not help.
I'm the biggest fan of OOP, and I practice OOP every day.
It's the most natural way to write code, because it resembles the real life.
Though, I realize that the OOP's virtualization might cause performance issues.
Of course that depends on your design, the language and the platform you chose (systems written in Garbage collection based languages such as Java or C# might perform worse than systems which were written in C++ for example).
I guess in Real-time systems, procedural programming may be more appropriate.
Note that not all projects that claim to be OOP are in fact OOP. Sometimes the majority of the code is procedural, or the data model is anemic, and so on...
Zyx, you wrote, "Most of the systems use relational databases ..."
I'm afraid there's no such thing. The relational model will be 40 years old next year and has still never been implemented. I think you mean, "SQL databases." You should read anything by Fabian Pascal to understand the difference between a relational dbms and an SQL dbms.
" ... the relational model is usually chosen due to its popularity,"
True, it's popular.
" ... availability of tools,"
Alas without the main tool necessary: an implementation of the relational model.
" support,"
Yup, the relational model has fine support, I'm sure, but it's entirely unsupported by a dbms implementation.
" and the fact that the relational model is in fact a mathematical concept,"
Yes, it's a mathematical concept, but, not being implemented, it's largely restricted to the ivory towers. String theory is also a mathematical concept but I wouldn't implement a system with it.
In fact, despite it's being a methematical concept, it is certainly not a science (as in computer science) because it lacks the first requirement of any science: that it is falsifiable: there's no implementation of a relational dbms against which we can check its claims.
It's pure snake oil.
" ... contrary to OOP."
And contrary to OOP, the relational model has never been implemented.
Buy a book on SQL and get productive.
Leave the relational model to unproductive theorists.
See this and this. Apparently you can use C# with five different programming paradigms, C++ with three, etc.
Software construction is not akin to Fundamental Physics. Physics strive to describe reality using paradigms which may be challenged by new experimental data and/or theories. Physics is a science which searches for a "truth", in a way that Software construction doesn't.
Software construction is a business. You need to be productive, i.e. to achieve some goals for which someone will pay money. Paradigms are used because they are useful to produce software effectively. You don't need everyone to agree. If I do OOP and it's working well for me, I don't care if a "new" paradigm would potentially be 20% more useful to me if I had the time and money to learn it and later rethink the whole software structure I'm working in and redesign it from scratch.
Also, you may be using another paradigm and I'll still be happy, in the same way that I can make money running a Japanese food restaurant and you can make money with a Mexican food restaurant next door. I don't need to discuss with you whether Japanese food is better than Mexican food.
I doubt OOP is going away any time soon, it just fits our problems and mental models far too well.
What we're starting to see though is multi-paradigm approaches, with declarative and functional ideas being incorporated into object oriented designs. Most of the newer JVM languages are a good example of this (JavaFX, Scala, Clojure, etc.) as well as LINQ and F# on the .net platform.
It's important to note that I'm not talking about replacing OO here, but about complementing it.
JavaFX has shown that a declarative
solution goes beyond SQL and XSLT,
and can also be used for binding
properties and events between visual
components in a GUI
For fault tolerant and highly
concurrent systems, functional
programming is a very good fit,
as demonstrated by the Ericsson
AXD301 (programmed using Erlang)
So... as concurrency becomes more important and FP becomes more popular, I imagine that languages not supporting this paradigm will suffer. This includes many that are currently popular such as C++, Java and Ruby, though JavaScript should cope very nicely.
Using OOP makes the code easier to manage (as in modify/update/add new features) and understand. This is especially true with bigger projects. Because modules/objects encapsulate their data and operations on that data it is easier to comprehend the functionality and the big picture.
The benefit of OOP is that it is easier to discuss (with other developers/management/customer) a LogManager or OrderManager, each of which encompass specific functionality, then describing 'a group of methods that dump the data in file' and 'the methods that keep track of order details'.
So I guess OOP is helpful especially with big projects but there are always new concepts turning up so keep on lookout for new stuff in the future, evaluate and keep what is useful.
People like to think of various things as "objects" and classify them, so no doubt that OOP is so popular. However, there are some areas where OOP has not gained a bigger popularity. Most of the systems use relational databases rather than objective. Even if the second ones hold some notable records and are better for some types of tasks, the relational model is unsually chosen due to its popularity, availability of tools, support and the fact that the relational model is in fact a mathematical concept, contrary to OOP.
Another area where I have never seen OOP is the software building process. All the configuration and make scripts are procedural, partially because of the lack of the support for OOP in shell languages, partially because OOP is too complex for such tasks.
Slightly controversial opinion from me but I don't find OOP, at least of a kind that is popularly applied now, to be that helpful in producing the largest scale software in my particular domain (VFX, which is somewhat similar in scene organization and application state as games). I find it very useful on a medium to smaller scale. I have to be a bit careful here since I've invited some mobs in the past, but I should qualify that this is in my narrow experience in my particular type of domain.
The difficulty I've often found is that if you have all these small concrete objects encapsulating data, they now want to all talk to each other. The interactions between them can get extremely complex, like so (except much, much more complex in a real application spanning thousands of objects):
And this is not a dependency graph directly related to coupling so much as an "interaction graph". There could be abstractions to decouple these concrete objects from each other. Foo might not talk to Bar directly. It might instead talk to it through IBar or something of this sort. This graph would still connect Foo to Bar since, albeit being decoupled, they still talk to each other.
And all this communication between small and medium-sized objects which make up their own little ecosystem, if applied to the entire scale of a large codebase in my domain, can become extremely difficult to maintain. And it becomes so difficult to maintain because it's hard to reason about what happens with all these interactions between objects with respect to things like side effects.
Instead what I've found useful is to organize the overall codebase into completely independent, hefty subsystems that access a central "database". Each subsystem then inputs and outputs data. Some other subsystems might access the same data, but without any one system directly talking to each other.
... or this:
... and each individual system no longer attempts to encapsulate state. It doesn't try to become its own ecosystem. It instead reads and writes data in the central database.
Of course in the implementation of each subsystem, they might use a number of objects to help implement them. And that's where I find OOP very useful is in the implementation of these subsystems. But each of these subsystems constitutes a relatively medium to small-scale project, not too large, and it's at that medium to smaller scale that I find OOP very useful.
"Assembly-Line Programming" With Minimum Knowledge
This allows each subsystem to just focus on doing its thing with almost no knowledge of what's going on in the outside world. A developer focusing on physics can just sit down with the physics subsystem and know little about how the software works except that there's a central database from which he can retrieve things like motion components (just data) and transform them by applying physics to that data. And that makes his job very simple and makes it so he can do what he does best with the minimum knowledge of how everything else works. Input central data and output central data: that's all each subsystem has to do correctly for everything else to work. It's the closest thing I've found in my field to "assembly line programming" where each developer can do his thing with minimum knowledge about how the overall system works.
Testing is still also quite simple because of the narrow focus of each subsystem. We're no longer mocking concrete objects with dependency injection so much as generating a minimum amount of data relevant to a particular system and testing whether the particular system provides the correct output for a given input. With so few systems to test (just dozens can make up a complex software), it also reduces the number of tests required substantially.
Breaking Encapsulation
The system then turns into a rather flat pipeline transforming central application state through independent subsystems that are practically oblivious to each other's existence. One might sometimes push a central event to the database which another system processes, but that other system is still oblivious about where that event came from. I've found this is the key to tackling complexity at least in my domain, and it is effectively through an entity-component system.
Yet it resembles something closer to procedural or functional programming at the broad scale to decouple all these subsystems and let them work with minimal knowledge of the outside world since we're breaking encapsulation in order to achieve this and avoid requiring the systems to talk to each other. When you zoom in, then you might find your share of objects being used to implement any one of these subsystems, but at the broadest scale, the systems resembles something other than OOP.
Global Data
I have to admit that I was very hesitant about applying ECS at first to an architectural design in my domain since, first, it hadn't been done before to my knowledge in popular commercial competitors (3DS Max, SoftImage, etc), and second, it looks like a whole bunch of globally-accessible data.
I've found, however, that this is not a big problem. We can still very effectively maintain invariants, perhaps even better than before. The reason is due to the way the ECS organizes everything into systems and components. You can rest assured that an audio system won't try to mutate a motion component, e.g., not even under the hackiest of situations. Even with a poorly-coordinated team, it's very improbable that the ECS will degrade into something where you can no longer reason about which systems access which component, since it's rather obvious on paper and there are virtually no reasons whatsoever for a certain system to access an inappropriate component.
To the contrary it often removed many of the former temptations for hacky things with the data wide open since a lot of the hacky things done in our former codebase under loose coordination and crunch time was done in hasty attempts to x-ray abstractions and try to access the internals of the ecosystems of objects. The abstractions started to become leaky as a result of people, in a hurry, trying to just get and do things with the data they wanted to access. They were basically jumping through hoops trying to just access data which lead to interface designs degrading quickly.
There is something vaguely resembling encapsulation still just due to the way the system is organized since there's often only one system modifying a particular type of components (two in some exceptional cases). But they don't own that data, they don't provide functions to retrieve that data. The systems don't talk to each other. They all operate through the central ECS database (which is the only dependency that has to be injected into all these systems).
Flexibility and Extensibility
This is already widely-discussed in external resources about entity-component systems but they are extremely flexible at adapting to radically new design ideas
in hindsight, even concept-breaking ones like a suggestion for a creature which is a mammal, insect, and plant that sprouts leaves under sunlight all at once.
One of the reasons is because there are no central abstractions to break. You introduce some new components if you need more data for this or just create an entity which strings together the components required for a plant, mammal, and insect. The systems designed to process insect, mammal, and plant components then automatically pick it up and you might get the behavior you want without changing anything besides adding a line of code to instantiate an entity with a new combo of components. When you need whole new functionality, you just add a new system or modify an existing one.
What I haven't found discussed so much elsewhere is how much this eases maintenance even in scenarios when there are no concept-breaking design changes that we failed to anticipate. Even ignoring the flexibility of the ECS, it can really simplify things when your codebase reaches a certain scale.
Turning Objects Into Data
In a previous OOP-heavy codebase where I saw the difficulty of maintaining a codebase closer to the first graph above, the amount of code required exploded because the analogical Car in this diagram:
... had to be built as a completely separate subtype (class) implementing multiple interfaces. So we had an explosive number of objects in the system: a separate object for point lights from directional lights, a separate object for a fish eye camera from another, etc. We had thousands of objects implementing a few dozen abstract interfaces in endless combinations.
When I compared it to ECS, that required only hundreds and we were able to do the exact same things before using a small fraction of the code, because that turned the analogical Car entity into something that no longer requires its class. It turns into a simple collection of component data as a generalized instance of just one Entity type.
OOP Alternatives
So there are cases like this where OOP applied in excess at the broadest level of the design can start to really degrade maintainability. At the broadest birds-eye view of your system, it can help to flatten it and not try to model it so "deep" with objects interacting with objects interacting with objects, however abstractly.
Comparing the two systems I worked on in the past and now, the new one has more features but takes hundreds of thousands of LOC. The former required over 20 million LOC. Of course it's not the fairest comparison since the former one had a huge legacy, but if you take a slice of the two systems which are functionally quite equal without the legacy baggage (at least about as close to equal as we might get), the ECS takes a small fraction of the code to do the same thing, and partly because it dramatically reduces the number of classes there are in the system by turning them into collections (entities) of raw data (components) with hefty systems to process them instead of a boatload of small/medium objects.
Are there any scenarios where a truly non-OOP paradigm is actually a
better choice for a largescale solution? Or is that unheard of these
days?
It's far from unheard of. The system I'm describing above, for example, is widely used in games. It's quite rare in my field (most of the architectures in my field are COM-like with pure interfaces, and that's the type of architecture I worked on in the past), but I've found that peering over at what gamers are doing when designing an architecture made a world of difference in being able to create something that still remains very comprehensible at it grows and grows.
That said, some people consider ECS to be a type of object-oriented programming on its own. If so, it doesn't resemble OOP of a kind most of us would think of, since data (components and entities to compose them) and functionality (systems) are separated. It requires abandoning encapsulation at the broad system level which is often considered one of the most fundamental aspects of OOP.
High-Level Coding
But it seems to me that usually the pieces of higher level solutions
are almost always put together in a OOP fashion.
If you can piece together an application with very high-level code, then it tends to be rather small or medium in scale as far as the code your team has to maintain and can probably be assembled very effectively using OOP.
In my field in VFX, we often have to do things that are relatively low-level like raytracing, image processing, mesh processing, fluid dynamics, etc, and can't just piece these together from third party products since we're actually competing more in terms of what we can do at the low-level (users get more excited about cutting-edge, competitive production rendering improvements than, say, a nicer GUI). So there can be lots and lots of code ranging from very low-level shuffling of bits and bytes to very high-level code that scripters write through embedded scripting languages.
Interweb of Communication
But there comes a point with a large enough scale with any type of application, high-level or low-level or a combo, that revolves around a very complex central application state where I've found it no longer useful to try to encapsulate everything into objects. Doing so tends to multiply complexity and the difficulty to reason about what goes on due to the multiplied amount of interaction that goes on between everything. It no longer becomes so easy to reason about thousands of ecosystems talking to each other if there isn't a breaking point at a large enough scale where we stop modeling each thing as encapsulated ecosystems that have to talk to each other. Even if each one is individually simple, everything taken in as a whole can start to more than overwhelm the mind, and we often have to take a whole lot of that in to make changes and add new features and debug things and so forth if you try to revolve the design of an entire large-scale system solely around OOP principles. It can help to break free of encapsulation at some scale for at least some domains.
At that point it's not necessarily so useful anymore to, say, have a physics system encapsulate its own data (otherwise many things could want to talk to it and retrieve that data as well as initialize it with the appropriate input data), and that's where I found this alternative through ECS so helpful, since it turns the analogical physics system, and all such hefty systems, into a "central database transformer" or a "central database reader which outputs something new" which can now be oblivious about each other. Each system then starts to resemble more like a process in a flat pipeline than an object which forms a node in a very complex graph of communication.

Practical uses of OOP

I recently had a debate with a colleague who is not a fan of OOP. What took my attention was what he said:
"What's the point of doing my coding in objects? If it's reuse then I can just create a library and call whatever functions I need for whatever task is at hand. Do I need these concepts of polymorphism, inheritance, interfaces, patterns or whatever?"
We are in a small company developing small projects for e-commerce sites and real estate.
How can I take advantage of OOP in an "everyday, real-world" setup? Or was OOP really meant to solve complex problems and not intended for "everyday" development?
My personally view: context
When you program in OOP you have a greater awareness of the context. It helps you to organize the code in such a way that it is easier to understand because the real world is also object oriented.
The good things about OOP come from tying a set of data to a set of behaviors.
So, if you need to do many related operations on a related set of data, you can write many functions that operate on a struct, or you can use an object.
Objects give you some code reuse help in the form of inheritance.
IME, it is easier to work with an object with a known set of attributes and methods that it is to keep a set of complex structs and the functions that operate on them.
Some people will go on about inheritance and polymorphism. These are valuable, but the real value in OOP (in my opinion) comes from the nice way it encapsulates and associates data with behaviors.
Should you use OOP on your projects? That depends on how well your language supports OOP. That depends on the types of problems you need to solve.
But, if you are doing small websites, you are still talking about enough complexity that I would use OOP design given proper support in the development language.
More than getting something to just work - your friend's point, a well designed OO design is easier to understand, to follow, to expand, to extend and to implement. It is so much easier for example to delegate work that categorically are similar or to hold data that should stay together (yes even a C struct is an object).
Well, I'm sure a lot of people will give a lot more academically correctly answers, but here's my take on a few of the most valuable advantages:
OOP allows for better encapsulation
OOP allows the programmer to think in more logical terms, making software projects easier to design and understand (if well designed)
OOP is a time saver. For example, look at the things you can do with a C++ string object, vectors, etc. All that functionality (and much more) comes for "free." Now, those are really features of the class libraries and not OOP itself, but almost all OOP implementations come with nice class libraries. Can you implement all that stuff in C (or most of it)? Sure. But why write it yourself?
Look at the use of Design Patterns and you'll see the utility of OOP. It's not just about encapsulation and reuse, but extensibility and maintainability. It's the interfaces that make things powerful.
A few examples:
Implementing a stream (decorator pattern) without objects is difficult
Adding a new operation to an existing system such as a new encryption type (strategy pattern) can be difficult without objects.
Look at the way PostgresQL is
implemented versus the way your
database book says a database should
be implemented and you'll see a big
difference. The book will suggest
node objects for each operator.
Postgres uses myriad tables and
macros to try to emulate these nodes.
It is much less pretty and much
harder to extend because of that.
The list goes on.
The power of most programming languages is in the abstractions that they make available. Object Oriented programming provides a very powerful system of abstractions in the way it allows you to manage relationships between related ideas or actions.
Consider the task of calculating areas for an arbitrary and expanding collection of shapes. Any programmer can quickly write functions for the area of a circle, square, triangle, ect. and store them in a library. The difficulty comes when trying to write a program that identifies and calculates the area of an arbitrary shape. Each time you add a new kind of shape, say a pentagon, you would need to update and extend something like an IF or CASE structure to allow your program to identify the new shape and call the correct area routine from your "library of functions". After a while, the maintenance costs associated with this approach begin to pile up.
With object-oriented programming, a lot of this comes free-- just define a Shape class that contains an area method. Then it doesn't really matter what specific shape you're dealing with at run time, just make each geometrical figure an object that inherits from Shape and call the area method. The Object Oriented paradigm handles the details of whether at this moment in time, with this user input, do we need to calculate the area of a circle, triangle, square, pentagon or the ellipse option that was just added half a minute ago.
What if you decided to change the interface behind the way the area function was called? With Object Oriented programming you would just update the Shape class and the changes automagically propagate to all entities that inherit from that class. With a non Object Oriented system you would be facing the task of slogging through your "library of functions" and updating each individual interface.
In summary, Object Oriented programming provides a powerful form of abstraction that can save you time and effort by eliminating repetition in your code and streamlining extensions and maintenance.
Around 1994 I was trying to make sense of OOP and C++ at the same time, and found myself frustrated, even though I could understand in principle what the value of OOP was. I was so used to being able to mess with the state of any part of the application from other languages (mostly Basic, Assembly, and Pascal-family languages) that it seemed like I was giving up productivity in favor of some academic abstraction. Unfortunately, my first few encounters with OO frameworks like MFC made it easier to hack, but didn't necessarily provide much in the way of enlightenment.
It was only through a combination of persistence, exposure to alternate (non-C++) ways of dealing with objects, and careful analysis of OO code that both 1) worked and 2) read more coherently and intuitively than the equivalent procedural code that I started to really get it. And 15 years later, I'm regularly surprised at new (to me) discoveries of clever, yet impressively simple OO solutions that I can't imagine doing as neatly in a procedural approach.
I've been going through the same set of struggles trying to make sense of the functional programming paradigm over the last couple of years. To paraphrase Paul Graham, when you're looking down the power continuum, you see everything that's missing. When you're looking up the power continuum, you don't see the power, you just see weirdness.
I think, in order to commit to doing something a different way, you have to 1) see someone obviously being more productive with more powerful constructs and 2) suspend disbelief when you find yourself hitting a wall. It probably helps to have a mentor who is at least a tiny bit further along in their understanding of the new paradigm, too.
Barring the gumption required to suspend disbelief, if you want someone to quickly grok the value of an OO model, I think you could do a lot worse than to ask someone to spend a week with the Pragmatic Programmers book on Rails. It unfortunately does leave out a lot of the details of how the magic works, but it's a pretty good introduction to the power of a system of OO abstractions. If, after working through that book, your colleague still doesn't see the value of OO for some reason, he/she may be a hopeless case. But if they're willing to spend a little time working with an approach that has a strongly opinionated OO design that works, and gets them from 0-60 far faster than doing the same thing in a procedural language, there may just be hope. I think that's true even if your work doesn't involve web development.
I'm not so sure that bringing up the "real world" would be as much a selling point as a working framework for writing good apps, because it turns out that, especially in statically typed languages like C# and Java, modeling the real world often requires tortuous abstractions. You can see a concrete example of the difficulty of modeling the real world by looking at thousands of people struggling to model something as ostensibly simple as the geometric abstraction of "shape" (shape, ellipse, circle).
All programming paradigms have the same goal: hiding unneeded complexity.
Some problems are easily solved with an imperative paradigm, like your friend uses. Other problems are easily solved with an object-oriented paradigm. There are many other paradigms. The main ones (logic programming, functional programming, and imperative programming) are all equivalent to each other; object-oriented programming is usually thought as an extension to imperative programming.
Object-oriented programming is best used when the programmer is modeling items that are similar, but not the same. An imperative paradigm would put the different kinds of models into one function. An object-oriented paradigm separates the different kinds of models into different methods on related objects.
Your colleague seems to be stuck in one paradigm. Good luck.
To me, the power of OOP doesn't show itself until you start talking about inheritance and polymorphism.
If one's argument for OOP rests the concept of encapsulation and abstraction, well that isn't a very convincing argument for me. I can write a huge library and only document the interfaces to it that I want the user to be aware of, or I can rely on language-level constructs like packages in Ada to make fields private and only expose what it is that I want to expose.
However, the real advantage comes when I've written code in a generic hierarchy so that it can be reused later such that the same exact code interfaces are used for different functionality to achieve the same result.
Why is this handy? Because I can stand on the shoulders of giants to accomplish my current task. The idea is that I can boil the parts of a problem down to the most basic parts, the objects that compose the objects that compose... the objects that compose the project. By using a class that defines behavior very well in the general case, I can use that same proven code to build a more specific version of the same thing, and then a more specific version of the same thing, and then yet an even more specific version of the same thing. The key is that each of these entities has commonality that has already been coded and tested, and there is no need to reimpliment it again later. If I don't use inheritance for this, I end up reimplementing the common functionality or explicitly linking my new code against the old code, which provides a scenario for me to introduce control flow bugs.
Polymorphism is very handy in instances where I need to achieve a certain functionality from an object, but the same functionality is also needed from similar, but unique types. For instance, in Qt, there is the idea of inserting items onto a model so that the data can be displayed and you can easily maintain metadata for that object. Without polymorphism, I would need to bother myself with much more detail than I currently do (I.E. i would need to implement the same code interfaces that conduct the same business logic as the item that was originally intended to go on the model). Because the base class of my data-bound object interacts natively with the model, I can instead insert metadata onto this model with no trouble. I get what I need out of the object with no concern over what the model needs, and the model gets what it needs with no concern over what I have added to the class.
Ask your friend to visualize any object in his very Room, House or City... and if he can tell a single such object which a system in itself and is capable of doing some meaningful work. Things like a button isnt doing something alone - it takes lots of objects to make a phone call. Similarly a car engine is made of the crank shaft, pistons, spark plugs. OOPS concepts have evolved from our perception in natural processes or things in our lives. The "Inside COM" book tells the purpose of COM by taking analogy from a childhood game of identifying animals by asking questions.
Design trumps technology and methodology. Good designs tend to incorporate universal principals of complexity management such as law of demeter which is at the heart of what OO language features strive to codify.
Good design is not dependant on use of OO specific language features although it is typically in ones best interests to use them.
Not only does it make
programming easier / more maintainable in the current situation for other people (and yourself)
It is already allowing easier database CRUD (Create, Update, Delete) operations.
You can find more info about it looking up:
- Java : Hibernate
- Dot Net : Entity Framework
See even how LINQ (Visual Studio) can make your programming life MUCH easier.
Also, you can start using design patterns for solving real life problems (design patterns are all about OO)
Perhaps it is even fun to demonstrate with a little demo:
Let's say you need to store employees, accounts, members, books in a text file in a similar way.
.PS. I tried writing it in a PSEUDO way :)
the OO way
Code you call:
io.file.save(objectsCollection.ourFunctionForSaving())
class objectsCollection
function ourFunctionForSaving() As String
String _Objects
for each _Object in objectsCollection
Objects &= _Object & "-"
end for
return _Objects
end method
NON-OO Way
I don't think i'll write down non-oo code. But think of it :)
NOW LET'S SAY
In the OO way. The above class is the parent class of all methods for saving the books, employees, members, accounts, ...
What happens if we want to change the way of saving to a textfile? For example, to make it compactible with a current standard (.CVS).
And let's say we would like to add a load function, how much code do you need to write?
In the OO- way you only need the add a New Sub method which can split all the data into parameters (This happens once).
Let your collegue think about that :)
In domains where state and behavior are poorly aligned, Object-Orientation reduces the overall dependency density (i.e. complexity) within these domains, which makes the resulting systems less brittle.
This is because the essence of Object-Orientation is based on the fact that, organizationally, it doesn't dustinguish between state and behavior at all, treating both uniformly as "features". Objects are just sets of features clumpled to minimize overall dependency.
In other domains, Object-Orientation is not the best approach. There are different language paradigms for different problems. Experienced developers know this, and are willing to use whatever language is closest to the domain.

Service-Orientation vs Object-Orientation - can they coexist?

There's been a lot of interest in Service-Oriented Architecture (SOA) at my company recently. Whenever I try to see how we might use it, I always run up against a mental block. Crudely:
Object-orientation says: "keep data and methods that manipulate data (business processes) together";
Service-orientation says: "keep the business process in the service, and pass data to it".
Previous attempts to develop SOA have ended up converting object-oriented code into data structures and separate procedures (services) that manipulate them, which seems like a step backwards.
My question is: what patterns, architectures, strategies etc. allow SOA and OO to work together?
Edit: The answers saying "OO for internals, SOA for system boundaries" are great and useful, but this isn't quite what I was getting at.
Let's say you have an Account object which has a business operation called Merge that combines it with another account. A typical OO approach would look like this:
Account mainAccount = database.loadAccount(mainId);
Account lesserAccount = database.loadAccount(lesserId);
mainAccount.mergeWith(lesserAccount);
mainAccount.save();
lesserAccount.delete();
Whereas the SOA equivalent I've seen looks like this:
Account mainAccount = accountService.loadAccount(mainId);
Account lesserAccount = accountService.loadAccount(lesserId);
accountService.merge(mainAccount, lesserAccount);
// save and delete handled by the service
In the OO case the business logic (and entity awareness thanks to an ActiveRecord pattern) are baked into the Account class. In the SOA case the Account object is really just a structure, since all of the business rules are buried in the service.
Can I have rich, functional classes and reusable services at the same time?
My opinion is that SOA can be useful, at a macro level, but each service probably still will be large enough to need several internal components. The internal components may benefit from OO architecture.
The SOA API should be defined more carefully than the internal APIs, since it is an external API. The data types passed at this level should be as simple as possible, with no internal logic. If there is some logic that belongs with the data type (e.g. validation), there should preferably be one service in charge of running the logic on the data type.
SOA is a good architecture for communicating between systems or applications.
Each application defines a "service" interface which consists of the requests it will handle and the responses expected.
The key points here are well defined services, with a well defined interface. How your services are actually implemented is irrelevant as far as SOA is concerned.
So you are free to implement your services using all the latest and greatest OO techniques, or any other methodology that works for you. ( I have seen extreme cases where the "service" is implemented by actual humans entering data on a screen -- yet everything was still text book SOA!).
I really think SOA is only useful for external interfaces (generally speaking, to those outside your company), and even then, only in cases when performance doesn't really matter, you don't need ordered delivery of messages.
In light of that, I think they can coexist. Keep your applications working and communicating using the OO philosophy, and only when external interfaces (to third parties) are needed, expose them via SOA (this is not essential, but it is one way).
I really feel SOA is overused, or at least architectures with SOA are getting proposed too often. I don't really know of any big systems that use SOA internally, and I doubt they could. It seems like more of a thing you might just use to do mashups or simple weather forecast type requests, not build serious systems on top of.
I think that this is a misunderstanding of object orientation. Even in Java, the methods are generally not part of the objects but of their class (and even this "membership" is not necessary for object orientation, but that is a different subject). A class is just a description of a type, so this is really a part of the program, not the data.
SOA and OO do not contradict each other. A service can accept data, organize them into objects internally, work on them, and finally give them back in whatever format is desired.
I've heard James Gosling say that one could implement SOA in COBOL.
If you read Alan Kay's own description of the origins of OOP, it describes a bunch of little computers interacting to perform something useful.
Consider this description:
Your X should be made up of Ys. Each Y should be responsible for a single concept, and should be describable completely in terms of its interface. One Y can ask another Y to do something via an exchange of messages (per their specified interfaces).
In some cases, an X may be implemented by a Z, which it manages according to its interface. No X is allowed direct access to another X's Z.
I think that the following substitutions are possible:
Term Programing Architecture
---- --------------- ------------
X Program System
Y Objects Services
Z Data structure Database
---- --------------- ------------
result OOP SOA
If you think primarily in terms of encapsulation, information hiding, loose coupling, and black-box interfaces, there is quite a bit of similarity. If you get bogged down in polymorphism, inheritance, etc. you're thinking programming / implementation instead of architecture, IMHO.
If you allow your services to remember state, then they can just be considered to be big objects with a possibly slow invocation time.
If they are not allowed to retain state then they are just as you've said - operators on data.
It sounds like you may be dividing your system up into too many services. Do you have written, mutually agreed criteria for how to divide?
Adopting SOA does not mean throw out all your objects but is about dividing your system into large reusable chunks.