0% found this document useful (0 votes)
5 views32 pages

Lecture 2

The document discusses various programming paradigms including structured, functional, and object-oriented programming, highlighting their historical development and fundamental principles. It emphasizes the importance of structured programming in creating provable functions and the role of object-oriented programming in managing dependencies. Additionally, it touches on immutability in functional programming and event sourcing as a strategy for managing application state.

Uploaded by

Hoàng Nguyễn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views32 pages

Lecture 2

The document discusses various programming paradigms including structured, functional, and object-oriented programming, highlighting their historical development and fundamental principles. It emphasizes the importance of structured programming in creating provable functions and the role of object-oriented programming in managing dependencies. Additionally, it touches on immutability in functional programming and event sourcing as a strategy for managing application state.

Uploaded by

Hoàng Nguyễn
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

Applied Programming and Design Principles

Lecture 2
Overview Of Programming Paradigms
Clean Architecture
A CRAFTSMAN’S
GUIDE TO SOFTWARE
STRUCTURE AND
DESIGN
Lesson’s objectives
• Structured Programming
• Functional Programming
• Object-Oriented Programming
PROGRAMMING PARADIGMS
• In 1938, Alan Turing laid the foundations of what was to become
computer programming
• He was not the first to conceive of a programmable machine, but he
was the first to understand that programs were simply data
• By 1945, Turing was writing real programs on real computers in code
that we would recognize
• Those programs used loops, branches, assignment, subroutines,
stacks, and other familiar structures
• Turing’s language was binary. Martin, R.C. (2017).
PROGRAMMING PARADIGMS [2]
• Since those days, a number of revolutions in programming have
occurred.
• First, in the late 1940s, came assemblers.
• In 1951, Grace Hopper invented A0, the first compiler. In fact, she
coined the term compiler.
• Fortran was invented in 1953
• What followed was an unceasing flood of new programming
languages—COBOL, PL/1, SNOBOL, C, Pascal, C++, Java, ad infinitum.
PROGRAMMING PARADIGMS [3]
• Another, probably more significant, revolution was in programming
paradigms.
• Paradigms are ways of programming, relatively unrelated to
languages
• A paradigm tells you which programming structures to use, and when
to use them.

Martin, R.C. (2017).


STRUCTURED PROGRAMMING [1]
• The first paradigm to be adopted (but not the first to be invented)
was structured programming, which was discovered by Edsger Wybe
Dijkstra in 1968
• Dijkstra showed that the use of unrestrained jumps (goto statements)
is harmful to program structure.
• He replaced those jumps with the more familiar if/then/else and
do/while/until constructs
An example of structured programming
STRUCTURED PROGRAMMING [2]
• Dijkstra started his career in the era of vacuum tubes, when
computers were huge, fragile, slow, unreliable, and (by today’s
standards) extremely limited.
• In those early years, programs were written in binary, or in very crude
assembly language
• Input took the physical form of paper tape or punched cards.
• The edit/compile/test loop was hours —if not days—long

Martin, R.C. (2017).


STRUCTURED PROGRAMMING [3]
• Dijkstra discovered that certain uses of goto statements prevent
modules from being decomposed recursively into smaller and smaller
units, thereby preventing use of the divide-and-conquer approach
necessary for reasonable proofs
• Other uses of goto, however, did not have this problem. Dijkstra
realized that these “good” uses of goto corresponded to simple
selection and iteration control structures such as if/then/else and
do/while.
STRUCTURED PROGRAMMING [4]
• Dijkstra knew that those control structures, when combined with
sequential execution, were special
• They had been identified two years before by Böhm and Jacopini,
who proved that all programs can be constructed from just three
structures: sequence, selection, and iteration.
STRUCTURED PROGRAMMING [5]
• In 1968, Dijkstra wrote a letter to the editor of CACM
• The title of this letter was “Go To Statement Considered Harmful.”
• The feedback from the programming world is mostly negative
• And so the battle was joined, ultimately to last about a decade.
• Eventually, the argument petered out. The reason was simple: Dijkstra
had won.
• Most modern languages do not have a goto statement
FUNCTIONAL DECOMPOSITION
• Structured programming allows modules to be recursively
decomposed into provable units, which in turn means that modules
can be functionally decomposed.
• That is, you can take a large-scale problem statement and decompose
it into high-level functions
• Each of those functions can then be decomposed into lower-level
functions, ad infinitum.
• Building on this foundation, disciplines such as structured analysis
and structured design became popular in the late 1970s and
throughout the 1980s Martin, R.C. (2017).
TESTS
• Dijkstra once said, “Testing shows the presence, not the absence, of
bugs.”
• In other words, a program can be proven incorrect by a test, but it
cannot be proven correct
• Structured programming forces us to recursively decompose a
program into a set of small provable functions.
• We can then use tests to try to prove those small provable functions
incorrect
• If such tests fail to prove incorrectness, then we deem the functions
to be correct enough for our purposes
OBJECT-ORIENTED PROGRAMMING
• Some definitions of OO:
• The combination of data and function
• A way to model the real world.
• Nature of OO: encapsulation, inheritance, and polymorphism.
Encapsulation
• Encapsulation is one of the fundamental principles of object-oriented
programming that allows you to hide the internal details of an object
and only expose a controlled and well-defined interface to the
outside world
• In C#, you can achieve encapsulation using classes, access modifiers,
and properties
An encapsulation example
Polymorphism
• Polymorphism is an application of pointers to functions.
• Programmers have been using pointers to functions to achieve
polymorphic behavior since Von Neumann architectures were first
implemented in the late 1940s
• OO languages may not have given us polymorphism, but they have
made it much safer and much more convenient
A polymorphism and inheritance example
Dependency inversion [1]

Martin, R.C. (2017).


Dependency inversion [2]
• HL1 calls the F() function in module ML1.
• The fact that it calls this function through an interface is a source
code contrivance. At runtime, the interface doesn’t exist. HL1 simply
calls F() within ML1
The power of OOP

Martin, R.C. (2017).


The power of OOP [2]
• The source code of the business rules never mentions the UI or the
database
• The UI, and the database can be compiled into three separate
components or deployment units (e.g., jar files, DLLs, or Gem files)
that have the same dependencies as the source code.
• In turn, the business rules can be deployed independently of the UI
and the database
• In short, when the source code in a component changes, only that
component needs to be redeployed.
What is OO finally?
• There are many opinions and many answers to this question
• To the software architect, however, the answer is clear: OO is the
ability, through the use of polymorphism, to gain absolute control
over every source code dependency in the system.
• It allows the architect to create a plugin architecture, in which
modules that contain high-level policies are independent of modules
that contain low-level details
FUNCTIONAL PROGRAMMING
• This paradigm is strongly based on the l-calculus invented by Alonzo
Church in the 1930s.
• In functional programming, the primary focus is on using pure
functions, which are functions that produce the same output for a
given set of inputs and have no side effects.
• Treats computation as the evaluation of mathematical functions and
avoids changing state and mutable data
Mutable and Immutable variables
• The Java program uses a mutable variable—a variable that changes
state during the execution of the program.
• That variable is i—the loop control variable.
• No such mutable variable exists in the Clojure program. In the Clojure
program, variables like x are initialized, but they are never modified
• Clojure is an example of functional programming
An example of a loop in Clojure programming
An example of a loop in Clojure programming
1. We use the loop macro to initiate a loop. The loop starts with i set
to 1.
2. Inside the loop, we use the if conditional to check if i is less than or
equal to 5.
3. If the condition is true, we use the do form to execute multiple
expressions. In this case, we use println to print the value of i, and
then we use recur to continue the loop with i incremented by one
using the inc function.
4. The recur function is used to create a tail-recursive call, allowing the
loop to continue with the updated value of i. This is a common
pattern in Clojure to create loops.
IMMUTABILITY AND ARCHITECTURE
• All race conditions, deadlock conditions, and concurrent update
problems are due to mutable variables
• In other words, all the problems that we face in concurrent
applications—all the problems we face in applications that require
multiple threads, and multiple processors —cannot happen if there
are no mutable variables. => a good point

Martin, R.C. (2017).


EVENT SOURCING
• Event sourcing is a strategy wherein we store the transactions, but
not the state.
• When state is required, we simply apply all the transactions from the
beginning of time
• More importantly, nothing ever gets deleted or updated from such a
data store. As a consequence, our applications are not CRUD; they are
just CR
• If we have enough storage and enough processor power, we can make
our applications entirely immutable—and, therefore, entirely
functional.
Summary #1
• Structured programming is discipline imposed upon direct transfer of
control.
• Object-oriented programming is discipline imposed upon indirect
transfer of control.
• Functional programming is discipline imposed upon variable
assignment.
Summary #2
• Software is not a rapidly advancing technology. The rules of software
are the same today as they were in 1946, when Alan Turing wrote the
very first code that would execute in an electronic computer. The
tools have changed, and the hardware has changed, but the essence
of software remains the same
• Software—the stuff of computer programs—is composed of
sequence, selection, iteration, and indirection. Nothing more.
Nothing less.
References
• Martin, R.C. (2017). Clean Architecture. Pearson Inc..
• MARCOTTE, C.-H. (2022) Atypical ASP.NET Core 6 design patterns
guide -: A solid adventure into architectural principles... and design
patterns using .NET 6, and C# 10. S.l.: PACKT PUBLISHING LIMITED.

You might also like