Related
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
I know that frameworks provide useful interfaces and classes that save a lot of time in implementation phase, so my question is:
Should the framework interfaces and classes be included in my project's class
diagram design or not?
and if it is,
Does this affect the reusability of the design if I decided to change
the framework in the future?
UML diagrams are intended to be read by different interest groups. Business likes to see requirements, use cases and activities. Architects/testers need that as a basis to develop/test the system. And the results produced by the architects (static and behavioral class diagrams) are meant to be read by programmers. Each reader group has a focus on certain parts but will eventually peek more or less into border areas (from their perspective).
So to answer your question: yes, frameworks shall be part of the model. Architects should pay attention as to how to cut the system. Frameworks should be designed with a different (broader) scope. So eventually you have frameworks that will be used only partially in a system. Or a system has a potential for a framework and it will be designed to be easily decoupled. Of course, this is a tricky task and architects need lots of experience to fulfill all the needs that come from business and eventually other stakeholders.
No, theoretically it shouldn't, but you're also free to do so.
As stated by the authors of UML: Rumbaugh, Jacobson, Booch
on The Unified Modeling Language Reference Manual at page 25
Across implementation languages and platforms. The UML is intended to be usable for systems implemented in various implementation languages and platforms, including programming languages, databases, 4GLs, organization documents, firmware, and so on. The front-end work should be identical or similar in all cases, while the back-end work will differ somewhat for each medium.
I've recently forayed into the world of functional programming (FP) and am wondering how to "think functionally" for even moderately sized applications? Especially w.r.t. the analysis and design of FPs.
With OOP we're trained to think in terms of objects, their attributes and relations. We model our analyses/designs using class and sequence diagrams. However, the same models seem to be a bad fit when designing for FPs. What are the equivalent modeling paradigms for functional programming? It seems DFDs maybe a good fit but I maybe wrong.
For example: I was thinking of designing a simulation of Monopoly, the board game using Haskell, just to learn the language. When doing OOAD you come up with classes like board contains items that have attributes/methods attached to it. You have player and various other objects and their associated relations that can be captured in a class diagram. And their interactions in a sequence diagram. However, these modeling paradigms doesn't seem to transfer well for functional programs. So just "how" do you model functionally?
Note: I'm looking for concrete references/examples that can explain how to analyze and design functional programs given that I'm coming from a heavily object-oriented way of thinking/modeling.
According to Simon Peyton Jones:
The language in which you write profoundly affects the design of
programs written in that language. For example, in the OO world, many
people use UML to sketch a design. In Haskell or ML, one writes type
signatures instead. Much of the initial design phase of a functional
program consists of writing type definitions. Unlike UML, though, all
this design is incorporated in the final product, and is
machine-checked throughout.
Source: Masterminds of Programming
So instead of drawing all the fancy UML diagrams, you actually write type definitions coupled with undefined in the design phase.
All of my programming these days consists of single-person projects. If I were collaborating on a project with other programmers, I think that writing type definitions and using undefined would be a good approach.
But I gather what you're really looking for is some advice about how you can learn to think functionally. So here are some thoughts.
When programming in Haskell, there are two ways I think about the program I'm writing.
If the program is mathematical, I think of the program as a set of equations.
Otherwise, I tend to think of the program as one or more chains of of data transformations. (So perhaps DFDs would be useful.)
So in your Monopoly example, my first thought would be to figure out how I'm going to represent the state of the board (e.g., which properties have houses, who owns them). Then I might have a function that transforms the board when someone buys a property, and other functions for other things players might do. (There's also monads for representing state, State and StateT. I might use them, if and when I feel they will make the code clearer, but I usually keep things basic to start.)
One of the mistakes I made most often as a beginner was to create a lot of unnecessary classes and data types.
Short answer: composition of smaller programs.
You first study the problem before you, then you develop a set of small operations (often in the form of combinators) that you reckon make sense in that problem's context, and finally you build the solution around those operations. I'm under the impression that all packages found on Hackage follow this approach.
In this way the final solution is (more often than not) simple, clear and elegant. As you can appreciate the aforementioned set of small operations you choose for your solution is critical; with practice, you'll develop the sensibility to pick it wisely.
My book suggestion is Pearls of Functional Algorithm Design, by Richard Bird, Google Books (preview). In this book you'll learn about the calculational approach to functional programming, which I think is most valuable.
Two books you might be interested in:
Structure and Interpretation of Computer Programs - a classic intro to CS textbook in Scheme. I think it's a must for programmers interested in FP.
How to Design Programs - similar to SICP, slightly more modern and focuses on design. The language of choice here is Racket.
If you want a hands-on project in Haskell, I'd recommend Write Yourself a Scheme in 48 Hours, a wonderful tutorial for implementing an interpreter for Scheme. AST manipulation is where FP (and especially Haskell) shines, so I think writing an interpreter is a good experience for new FP programmers.
My perspective regarding the FP vs OO analysis and design debate is the following:
OOAD and DDD (Domain-Driven Design) are very useful tools for software systems decomposition;
FP has types, OO has classes and interfaces: they are dual in different worlds;
FP has type instances, OO has class instances (aka, objects in OO);
Use composition in FP, where in OO you would use inheritance;
Both FP and OO languages come with polymorphic constructs;
Both FP and OO use collections (sets, lists and maps) to make connections between instances (of types in FP, and of classes in OO);
Associations in FP are typically implemented as collections of instance IDs, whereas absensein OO they are implemented as collections of references to the memory locations of objects. This comes from the immutability property of data structures in FP.
Most books in FP, like those referred in the other answers before mine, do not show you how to design (aka, decompose) complex real-world problems. They generally demonstrate FP's features with very short examples (e.g., compare them with the examples in Craig Larman's Applying UML and Patterns excelent book, and judge yourself).
For something more close to what could be called Functional-Oriented Analysis and Design (FOAD), I recommend these:
Elixir in Action
Domain Modeling Made Functional: Tackle Software Complexity with Domain-Driven Design and F#
Functional and Reactive Domain Modeling
Functional Programming in Scala
DDD, OOAD, and FOAD, can be implemented in any programming language, however some programming languages offer constructs that make these approaches easier or harder to implement, but they are perfectly practical. This is evident by the many sources you can find discussing DDD in the context of FP.
Dr. Alan Kay said this regarding the essence of OOP (here):
OOP to me means only messaging, local retention and protection and
hiding of state-process, and extreme late-binding of all things. It
can be done in Smalltalk and in LISP. There are possibly other systems
in which this is possible, but I'm not aware of them.
Following this statement, Joe Armstrong, one of Erlang's creator, an FP language with important uses in the industry (e.g., WhatsApp), argues that Erlang is perhaps the most OO language around (see this interview also featuring Ralph Johnson).
Also, some say that Erlang is the best language that captured the essence of OO programming: the passing of messages between objects.
Hope this was helpful.
I can only speak from the perspective of Erlang OTP. We think in terms of processes, which have a state and functions. So in the state the process will have all the "variables" and handler functions react to data the process receives in its message queue. They act on the received data, possibly alter their own state, possibly return some data and/or have some side effects. The state can be stored in a map or a record or any other valid data type. Usually we define a record called state() or loopData().
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.
What is meant by the "dependency inversion principle" in object-oriented programming? What does it do?
In object-oriented programming,
the dependency inversion principle refers to a specific form of decoupling where conventional dependency relationships established from high-level, policy-setting modules to low-level, dependency modules are inverted (e.g. reversed) for the purpose of rendering high-level modules independent of the low-level module implementation details.
The principle states:
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
Source
The main reason for using dependency inversion is to allow for different implementations of those lower-level modules to be selected either at compile-time in the application or at runtime by configuration. This is a big win for testing because it allows you to completely isolate the code being tested and use mock objects.
Another way this is a huge help is for client deployments. Let's say you have different customers with different auth systems, or different databases, or reporting systems, or whatever. You can configure their system at deployment time by changing an XML file to choose the right implementations of those components to load, with no code changes at all.