Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Persian
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
when I say that this video is probably
the most important programming video
you're ever going to watch it's partly
because what I'm going to tell you is
distinctly a minority position among
programmers probably 5% or under
programmers will tell you that
definitively object-oriented programming
is just not a good idea and in fact is
going to lead you astray maybe you'll
have another 20-30 percent of
programmers who will hand in Hall and
say that it has some virtues and some
weaknesses and it might be better
applied to some problems than others I'm
not telling you that I'm telling you
definitively no object-oriented
programming doesn't fit any problem and
you shouldn't take it seriously this is
almost certainly not what you were told
in school if you attended a programming
course in the last 15 years or you read
most educational materials about
programming the the pervasive default
assumption is just well object-oriented
programming is the right way to go and
it's just a settled matter so I
reiterate this is probably going to be
the most important video you watch about
programming because it's going to tell
you something you're not going to get
from a vast majority of other sources
first off I'm going to try and make
clear exactly what I'm complaining about
and what I'm not complaining about and
then I'm going to try and explain well
what is object oriented program really
because if we don't nail that down it's
almost impossible to criticize and then
I'll try and account for it well if
object or a mean isn't good why does it
dominate the industry that's kind of an
important question actually and then
I'll actually get into well why does
object coming toward me not work what's
bad about it and then lastly if I'm
telling you to not program in an
object-oriented style than what you do
instead what is the alternative
it's called procedural programming but
what does that look like exactly so what
are the problems with object-oriented
programming well first off the problem
is really not classes per se that is I
think it's actually possible to program
occasionally with classes in a way
that's fairly benign I don't think it's
particularly beneficial but for
aesthetic reasons it might seem more
pleasing to have an explicit association
between certain functions and certain
dip types doing this pervasively though
as I'll make clear is a really bad idea
that's where everything goes wrong is
when you try and shove every function of
your code every behavior into an
association with the datatype that leads
to disaster secondly I don't think the
problem with object-oriented programming
is about performance I recommend you
watch this talk by Mike Acton called
data oriented design and
plus he makes some very interesting
points and provides some insight into
that role the program in which most of
us don't do but I think he over States
his case fine there's a lot of software
out there that should be written with
much more regard for a performance but I
think there's tons of software that just
really doesn't apply you'll also hear
complaints about excessive abstraction
from generally the same people people
like Mike Acton and again here I think
they're overstating the case I think
abstraction is actually a worthy goal in
practice most abstractions aren't good
it takes a long long time to develop
good ones and as I'll explain a major
problem with object-oriented as it does
tend to produce abstractions that aren't
any good that's the real problem not the
idea of abstraction itself another
interesting talk to watch is one by
Abner coimbra called what programming is
never about and the thing which he says
programming is never about is code
prettiness how code looks aesthetics his
main point is that programmers typically
focus too much on surface concerns about
their code rather than stuff that really
matters I think though he actually
simply misstates his case or or rather
his thesis doesn't really follow from
his arguments which are generally valid
I think when really pressed he would
admit that elegance simplicity
flexibility readability and
maintainability structure all these
things you might file under code
aesthetics I think you admit actually do
matter but I think the more accurate way
to spend his point is that these surface
level virtues of code are good things
and actually important but object doing
and programming and abstraction heavy
programming in general fails to deliver
them in fact it provides just the
illusion of these things object-oriented
programming is sold on the basis that it
supposedly provides these things but
particularly simplicity and elegance it
actually makes things worse lastly be
clear that I'm pushing procedural
programming not necessarily functional
programming which is a different thing
as I will make clear in a moment I
happen to think that functional
programming actually is the future of
higher level code I think it may
actually be the default way we program
at a higher level in ten years from now
or something
but there are serious efficiency
problems that make functional
programming not really viable in certain
domains of programming and so my message
is whether your code ends up functional
or imperative that's a separate matter
we're go
allas your code should be procedural
rather than object-oriented so it's a
good time now to make clear exactly what
are the competing paradigms of
programming that we're really talking
about there are four main possibilities
your code confers to be both procedural
and imperative procedural meaning that
you have no explicit association between
your datatypes and your functions your
behaviors an imperative meaning that we
just mutate state whenever we feel like
it we don't have any special handling of
shared State which can cause problems as
your code gets larger and larger and
more complex but in procedural and
imperative programming we just cope with
the problems as they arise and you can
think of this style of programming as
being basically the default it's the the
obvious way to get work done so this is
really how all programming was done in
the early days of computers but then
starting in the 60s as programs got more
more complicated people began thinking
about well how do we solve this problem
of shared state because it really can
get out of hand and so we got two major
prescriptions on how to handle the
problem one of these prescriptions says
that our code should be procedural yet
functional meaning that all or most of
the functions that make up our code
should be pure they should not deal with
state and so programming in the style we
would tackle the problem of shared state
by minimizing state trying to get rid of
as much of it as possible
the other prescription people came up
with said that our code should be
object-oriented and imperative and the
strategy here is that we simply
segregate our state we take the state
that makes up a program and instead of
sharing it promiscuously we try and
divide and conquer the problem we
package it into these encapsulated units
that we call objects and objects contain
other objects and so forth and that's
how we conquer the problem and these two
prescriptions are actually orthogonal to
each other we can do both the functional
business to minimize the amount of state
which our program deals with and then
whatever state is left over we can then
segregate into separate units of
encapsulation and in fact I think this
combination approach may actually be the
ideal way to structure programs at least
in terms of high-level code where we
don't care so much about efficiency as
I'll explain I think segregating state
is actually a valid strategy up to a
certain level of detail certain level of
complexity and so if we first minimize
the amount of
a twitch our code deals with it then
becomes a viable strategy to segregate
the Romanian state you may have noticed
in my definition of object-oriented I
said nothing about inheritance and that
is because inheritance is simply
irrelevant no one defends it anymore
even people who advocate for
object-oriented
well very very commonly these days tell
you to be very very careful in using
inheritance or maybe not to use it at
all and so it's not really pertinent to
any argument about whether
object-oriented programming is good or
bad for similar reasons I didn't say
anything about polymorphism in my
definition because polymorphism really
good or bad isn't exclusive to
object-oriented programming you can have
procedural code that is polymorphic and
in fact even more polymorphic than is
typically available in most
object-oriented languages so it's really
not part of the discussion as far as I'm
concerned when I complained about
object-oriented programming I'm really
complaining about one idea encapsulation
encapsulation does not work or as I
should qualify this encapsulation does
not work at a fine-grained level which
is the core of what object-oriented
ideology prescribes that we need to take
the state of our programs and divide and
conquer that problem by chopping it up
into tiny little pieces that is the
nature of object-oriented code and it
doesn't work it leads to madness before
delving into why object-oriented
programming doesn't work it is important
to address this mystery of well if
object-oriented isn't so great
why does it now dominate the industry
and why is it done so for almost last
twenty years I've heard it sometimes
suggested that well this was an
imposition of management management
wants interchangeable developers so that
we can have a cookie cutter assembly
line development process hence business
types were really enthusiastic about
object oriented programming promises
about code reusability and
compartmentalization it's a theory that
sounds plausible to me but the main
sticking point is that object-oriented
programming doesn't actually deliver
these promises you'd think people would
have noticed sometime in the last 20
years yet they seem not to have noticed
I'm also skeptical of the idea that
management actually really inserted
themselves in these technical decisions
that often I suppose once a
object-oriented
and that became the pervasive norm then
yeah sure
management would push towards doing what
everyone else is doing so that they can
draw from the
larger talent pool but otherwise aside
from pushing engineers to just go along
with the legacy system and not rebuild
everything I just don't think that many
business managers really care that much
about technical decisions I'm much more
inclined to think that object-oriented
programming is something that
programmers did to themselves and the
question is then well why I think a big
part of the answer simply comes down to
Java when it was first introduced in the
mid-90s Java seemed like a welcome
reprieve to many programmers compared to
the alternatives Java seemed really
simple for example on the PC this is
what application development looked like
you had to use the win32 api and see and
not only that programmers have to
concern themselves with memory
management as you do and see but on top
of that win32 just doesn't feel like the
C that you would learn from books that's
not what you would learn from knr it's
not what you would learn in school it's
all this excess and macro heavy stuff on
top that is really mystifying even the
tools you would use to write C programs
on a Windows platform the the visual
studio tools you know wouldn't be the
same as what you would learn in
university probably where you probably
had a UNIX system and that's what you
learned so it was already this platform
with a quite high barrier to entry but
then also in this period it was
undergoing this ugly transition from win
16 to win 32 and so you can begin to see
why programmers were desperately looking
for some way out the only real
alternative at the time in PC
programming was what Visual Basic but
that was another effective Microsoft
platform you're locking yourself in too
and I suppose otherwise you might use
peskow or Delfy but that platform had
its own issues and so it shouldn't be
too surprising that when Sun
Microsystems came along and said here's
this free thing that everyone can use
across all platforms that got people's
attention and Java had other things
going for it it certainly seemed more
accessible just in terms of like its
naming conventions for example you look
at the Java API s and you see things
like file input stream which is not
cryptic at all yes there are definitely
issues and how abstracted many of the
api's are and you know having to derive
base classes to use the API as and all
that nonsense but on first glance on
surface inspection it certainly seems
like a friendlier system it's not like
UNIX where you have stuff like ioctl
which is you're supposed to know is
input/output control and other really
horrible abbreviations and then when 32
had the same thing you know LPC TST RS
stands for
Oh what's long pointer to a Const teach
our string so even if you know what a t
char is and a long pointer is you're
stuck in this world where everything is
cryptically abbreviated and it's just as
goddamn puzzled that you have to figure
out at every step
Java came in and said no we don't
necessarily have to program that way we
can write real programs that don't have
to be horribly cryptic in that way and
then Java took things too far in the
other direction but that's again we'll
get to that Java also smartly had the C
like syntax the curly brace syntax so
superficially at least it seemed
familiar to programmers from C and C++
and it seemed like real programming it
has curly braces after all and then the
whole compilation to VM bike code
business was again very alluring to
programmers trying to escape their
platform headaches and then Java also
offered some very basic niceties like
proper name spaces without header files
for Christ's sake we still have to deal
with header files to do our real
programming in C and C++ at least 20
years after we should have ditched them
if for this one thing alone I think it's
worth giving Java some credit it
mainstream programming without header
files and then of course also very
alluring garbage collection I know some
hard core low-level programmers out
there will insist the garbage collection
is never necessary it's never a good
idea but whether or not that's the case
it's really hard to argue with the
appeal it shouldn't be surprising that
the vast armies of people doing business
crud applications wanted to stop
thinking about memory management Java
also mainstreamed exceptions as the
primary way to handle errors and
whatever problems this may have in
practice I think it definitely seems
appealing because the alternative is
ugly the alternative is what we do in C
and C++ of having to have an inbound err
return value or likes you know saving to
global and checking the global after
everything you call it's not pretty
going with a little return and that
style probably the better way to go but
that's not the solution Java came up
with and so normalize this other thing
that seemed better at the time I think
some people also came to like the
subject-verb-object nature of method
calls over straight function calls
because well this is just what we do in
English its subject first then verb than
object I myself don't find it all that
appealing
I prefer consistency and I think the
distinction between subject and object
in many many cases gets very very
which is one of the problems with
object-oriented programming as we'll get
to but the style of syntax in Java led
to this convenience people I think since
then have become addicted to which is in
their IDs it offers them for this data
type what are my options what can I do
with this thing it seems to enable
Stella programming where you can just
sort of browse you don't have to hold
all the options in your head you just
have a vague notion of way I'm going to
take that thing and transform into this
other thing I don't remember exactly
what the methods called we'll just grope
my way there using Auto completion in my
IDE again there's really actually no
reason you couldn't have the same style
of convenience in a purely procedural
language you just have an auto
completion for given this first argument
what functions take this type as its
first argument and a being effectively
the same thing really but because of
quirks of history and syntax design this
particular editing convenience has been
implemented for languages like Java but
generally not straight procedural
languages and I think method
auto-completion may actually largely
explain why people sometimes claim that
object oriented API is feel easier to
use it's because you can largely
autocomplete your way through most of
the usage another thing Java is seem to
have going for it is that back in the
mid-90s this was the heyday of GUI
programming and it seemed really logical
to map components as we see them in a
GUI window and classes in an
object-oriented program that seemed like
a very natural correspondence this was
the most tangible version of the real
world modeling which object-oriented
promised at the time it seemed like a
very plausible story and on top of that
you have the virtue of Java Bean
supposedly cross-platform with the Java
swing API so you can write gooeys that
will run on any system they'll look
horribly ugly but at least hey they run
on everything you could do so-called rad
rapid application development of GUI
applications like you do in Visual Basic
except in Java you're not locked into
Microsoft's platform so the funny thing
to me about Java is that I think in an
ultimate history it could have had
virtually all the same success if not
even more perhaps if it weren't
object-oriented at all it could have
just been a straight procedural language
and would have had still a big long list
of attractive selling points we could
have had all the same portability the
same garbage collection
same exception handling and so forth
down the line without any of the object
oriented miss or at the very least
without forcing everything into the mold
of classes you could have it of a
language like Python say where there are
classes but also just straight
procedural code if you want and they can
live side by side just fine so this
still is this question Java aside there
seems to be some appeal to object
oriented programming in itself inand
what is that well I think very simply if
you go back to the 60s and 70s as people
were grappling with the problems of
software systems getting larger and
larger people tried to identify units of
code abstraction that were larger than
individual functions and data types it's
natural to want to describe any complex
system in terms of large scale
components you know if you talk about
human anatomy that you don't explain it
first in terms of microbiology that
would be nuts we first talked about very
major organs like the brain and the
heart and the kidneys and so forth as
software gets larger and larger it felt
like these units of code we were
building out of the base materials these
data structures and functions they
became smaller and smaller relative to
the whole sadly though the one general
answer people could come up with of what
is a unit of code abstraction bigger
than a function and bigger than a data
type is just simply a combination of the
two and hence objects were born we took
our functions in our data types and we
associated them together into these
larger units we want to think in terms
of paragraphs rather than individual
sentences and object-oriented
programming seem to have an answer for
how we could do that it's also very
natural that as we build larger and
larger systems and complex things as
much as possible we want simple rules to
guide us object-oriented programming
seem to present a unit of abstraction
and a set of guidelines whereby we can
incrementally accrete larger and larger
systems this line of thinking is what
led us to patterns and then the so
called solid principles and dependency
injection and test-driven development
and all this stuff which has
subsequently been piled on by many
people who insist that this is now the
one true way to do object-oriented
programming but to me all these best
practices represent band-aids
they are compensation for the fact that
the original vision of object-oriented
out and every few years there's a new
ideology in town about how we actually
do object and programming for real this
time
it's very easy to miss this dynamic I
know I did for several years because I
think within all of these addendums to
object marry programming there there's
lots of mystical speech dancing around
genuine insights but it's not quite
cohesive object when your programming
feels like this circle which we've been
trying to square for over a generation
now finally let's talk about what's
really wrong with object-oriented
programming specifically encapsulation
which is the linchpin of the whole thing
so consider what is an object an object
is this bundle of encapsulated state and
we don't interact with the state of that
object directly all interactions with
that state from the outside world come
in through messages messages to the
object the object has a defined set of
messages which it will receive called
its public interface and so we have
private information hidden behind the
public interface when an object receives
a message it may in turn send messages
to other objects and so we can conceive
of an object-oriented X all
communicating with each other by sending
messages many people today forget though
that the original conception of a
message is not exactly synonymous with
just a method call yes in practice it
means calling methods but a message
strictly speaking sends only copies of
state it doesn't send references a
message sends and returns information
about state not state itself and while
wait a minute objects themselves are
state and this has some interesting
consequences it means that strictly
speaking messages cannot pass around
object references I've never seen a Java
or C sharp code base that ever follow
this rule perhaps some small talk
programs have but in general this rule
is not observed at all and probably for
good reason as we'll discuss but anyway
if we take the role seriously it means
then for an object to send a message to
another object the first object must
hold a private reference to that other
object because otherwise how is it going
to talk to it to talk to knob jekt you
have to have a reference to it and where
is it object going to get a reference to
another object if it can't get object
references from messages the references
which an object needs have to all be
there at the object's inception they
have to be there for the whole lifetime
of the object and there's an even deeper
consequence which is that if an object
is sending messages to another that
other object is part of the first
object's private state and by the
principle of account
halation an object should be responsible
for all the objects which it sends
messages to this should be obvious if
you consider that messages indirectly
read and modify state when B sends a
message to a here it's messing with the
state of a indirectly shirt but is still
messing with its state and so what
happens when other objects come along
and send messages to that same object
what's happening here we have shared
state it's hardly any different than if
you had a single global variable being
shared by say ten functions if you have
an object receiving messages from ten
other objects those objects are all
effectively tied together because
they're implicitly sharing this state
sure the interactions with that state
are indirect through public methods but
those methods are providing very trivial
kinds of coordination of the state you
can impose rules through the access or
methods like saying oh if you access
this field it's a number well you can
only increment that number you can't
mutate it in any other way fine but it's
a very trivial kind of protection the
hard problems of shared state are much
much deeper where in the system of ten
objects all sharing the state is the
real coordination and the answer is
there isn't any as soon as you have
objects being shared encapsulation just
flies out the window so if we're taking
encapsulation seriously the only real
way to structure a program to structure
our objects as a graph is not as a
free-form graph but as a strict
hierarchy at the top of our hierarchy we
have an object representing effectively
the whole program it's our god object
and that has its direct children which
represent the sub components and those
children in turn have their own sub
components and so on down the line and
each object in the hierarchy is
responsible for its direct children and
the message is being passed strictly
only ever go from parent to their direct
child the god object here for example is
not supposed to reach down to its
grandchild it has to do all of its
interactions with this grandchild
indirectly through the grand child's
parent otherwise who really is
responsible for that object who is
managing its State supposed to be the
direct parent and so what happens when
we have some sort of cross-cutting
concern like down in the hierarchy it
turns out oh wait there's some business
that that object has with another object
and a totally different branch of the
hierarchy how do they talk to each other
well not directly everything has to go
through their common ancestor for a to
send a message to be here it can't
actually directly invoke any kind of
method it has to mutate its own state
and
way and then information about that
state that new intention of the object
gets returned from a message sent from
aids parent days parent intern same
thing has to happen so it gets back up
to the common ancestor and then only
finally when we get to the common
ancestor can that intent be realized as
a series of message calls but not
directly down to B it has to be
bucket-brigade it down through the
hierarchy that is how you handle
cross-cutting concerns in a strict
encapsulated hierarchy obviously no one
writes programs this way or at least no
one writes whole programs this way and
for good reason is an absurd way to have
to write your code now you might argue
that people do follow these principles
in practice they just do so
inconsistently and perhaps there is some
value in a code base where you apply
these principles inconsistently perhaps
half-assed encapsulation actually gets
us something so imagine we have some
sort of freeform graph of objects making
up a program and we decide oh well
there's this subsystem of objects that
together should be their own
self-contained encapsulated hierarchy of
objects and so we're going to refactor
our code well very often what that means
is not only do we have to do a lot of
complicated rethinking of the structure
of the relationships here of what calls
what on the other objects we very
typically have to introduce more objects
like say here to represent this whole
new subsystem we probably have to
introduce some new sub god object you
know some ruler of this subsystem now
all interactions with the subsystem have
to be rican sexualized as going through
this minor deity so say we successfully
do this refractory and now while our
code doesn't follow the principles of
encapsulation perfectly it's doing so in
a half consistent way and maybe there's
some benefit there well I think what
tends to happen is subsequently we
decide oh wait we need some new
interaction between elements of this
encapsulated subsystem and instead of
having to do the hard work of figuring
out how exactly it all gets coordinated
from the roots of that subsystem the
temptation is to just handle the
business directly but if we want to do
the proper thing we have two options
that maybe it turns out that that stuff
external to the subsystem actually just
needs to get integrated into that
subsystem and so it comes under the
purview of the subsystems root but
otherwise we now have two subsystems
that need to coordinate and who's going
to do the coordination well now we need
a new subsystem god
responsible for the collective business
of these two subsystems and now all
interactions of these two subsystems
have to go through this root object but
also all interactions with the outside
world and these two subsystems have to
go through this new root object so as
you can see chances are really good that
what you would actually do is say
it and just do this you would just reach
in and have the objects directly
interact with each other whether they
should properly do so or not and now
where is the encapsulation what's the
point whether you follow the rules
strictly or loosely you're in a bad
place if you follow the rule strictly
most things you do end up at being very
unobtrusive these entities tends to be
very abstract and nebulous but
alternatively if you follow the rules
loosely what are you even getting why
are you bothering what is the point when
I look at your object-oriented code base
what I'm going to encounter is either
this over-engineered giant tower of
abstractions or I'm going to be looking
at this inconsistently architected pile
of objects that are all probably tangled
together like Christmas lights you'll
have all these objects giving you a warm
fuzzy feeling of encapsulation
but you're not going to have any real
encapsulation of any significance what
people tend to create when they design
object-oriented programs are overly
architected buildings where the walls
have been prematurely erected before we
have really figured out what the needs
of the floor plan are and so what
happens is down the line turns out oh
wait we need to get from this room over
here to that room over there but oh wait
we've erected barriers in between so we
end up busting a bunch of holes through
all the walls like the kool-aid guy and
the resulting pattern is really not
organized at all it's just Swiss cheese
we thought we were being disciplined
neatly modularizing all the state but
then the requirements changed or we just
didn't anticipate certain details of the
implementation and we end up with a mess
the lesson we should take from this is
to be very careful about erecting
barriers about imposing structure it's
actually better to start out with a
free-form absence of structure rather
than impose a structure that will likely
turn out to not really fit our problem
bad structure that doesn't really fit
our problem not only makes it harder to
implement the code in the first place
that hinders change and it confuses
anyone who looks at our code because
it's implying one thing but then what's
really going on is another in the
object-oriented world we have to think
about all these graphs we have
think about an inheritance hierarchy we
have to think about a composition graph
we have to think about data flows
between the object and also we're
thinking about a coal graph the
liberating thing about procedural code
is there's just the coal graph we also
of course do have to think about how our
data is structured and how our data gets
transformed throughout the course of the
program but the beauty of procedural
code is that we can think about that
totally independent of any notion of
responsibilities when I'm looking at my
data I can think just about my data and
when I'm looking at my functions I'm not
thinking about all these self-imposed
barriers I'm not constantly trying to
group and modularize everything into
these small units of so-called single
responsibilities when I sit down to
write object-oriented code I always have
to play this game I have this mental
list of the obvious data types which my
code will deal with and have the
separate mental list of all the imagined
behaviors I want in my program although
the functionality I imagine it to have
and then what object-oriented ideology
demands is that I take all my behaviors
and I somehow associate each one with
one of my data types inevitably what
this means in any non-trivial program is
I'm actually going to have to introduce
all sorts of additional data types
just to be these containers for certain
behaviors which otherwise don't
naturally fit with any of my obvious
data types the data types I knew I
actually wanted because they represent
actual data I need
in fact as programs get larger and
larger in object-oriented code it tends
to be that these unobvious unnatural
data types tend to actually predominate
you end up with majority of so-called
data types which really aren't there
because they're representing data they
exist simply as a text to conform to
this ideology about code modular ization
very quickly we end up in what Steve
Yeager called the kingdom of nouns where
every aspect of our program has to be
rican Sepp Shu alized as not just mere
standalone verbs you know functions you
have to be Rican sexualised as nouns
things that represent a set of behaviors
and so what we get in our
object-oriented code bases are all these
service classes and manager classes and
other what I call Dewar classes these
very nebulous and abstract entities even
when dealing with data types and
behaviors that are relatively concrete
which have fairly visible connections to
the functionality apparent to actual
uses of the program even here the
matchmaking game constantly presents us
with these obnoxious philosophical
dilemmas in object-oriented analysis
into
design we constantly have to ask ourself
stupid questions like should a message
send itself because maybe instead we
should have some sender object which
sends messages or wait a minute maybe
there should be a receiver object which
receives messages or a connection object
which transmits messages so very quickly
the real world model in which object
oriented programming promises becomes a
fool's game where there aren't any real
good answers in my experience object
oriented analysis and design very
quickly becomes analysis paralysis if
you take the ideology seriously as I did
you're going to waste a lot of time
hemming and hawing about to
conceptualize these elements of your
program object-oriented programming is
generally sold to students on the basis
of these trivial examples that neatly
model real-world taxonomy but what we
get in practice from object-oriented
analysis and design is a lot of very
abstract excess structure with no
obvious real-world analogues note here
that programmers have their own peculiar
definition of abstract when programmers
talk about abstraction they're generally
talking about simplified interface over
complex inner workings what's odd about
this is that a more general usage
abstract as a connotation of being hard
to understand something which is
abstract has no resemblance to the
things of common daily life and it turns
out that most things which programs do
are abstract in this sense and so it
shouldn't be surprising that we have
great difficulty conceptualizing the
components of a typical program in terms
of neatly self-contained modules
particularly modules which have any
real-world analogue when we pollute our
code with generic entities like managers
and factories and services we're not
really making anything easier to
understand we're just putting a happy
face on the underlying abstract business
and for every excess layer of
abstraction or getting more abstract
NISS in attempting to neatly modular
eyes and label every little fiddly bit
that our program does we're actually
just making our program harder to
understand something that happens all
the time when I look at object-oriented
code bases is that I'll try and find the
parts in code that correspond to some
user visible functionality but trying to
find the functionality going by clues
from the names of classes and the names
of methods tends to be very misleading
very typically my expectation that
shanell DX would be in the class named X
turns out to be wrong because the
abstract nature of what we typically do
in programs generally necessitates that
functionality is not going to be
self-contained it's not going to neatly
fit into one neat module and so the
class which is called X will very
superficially relate to X but then all
the real work is done elsewhere
scattered throughout the code this makes
me question what is the value of having
a class called X if it doesn't really
contain all the business of X what this
class X really represents is actually
misleading code structure and how is
that helpful how is that conducive to
understanding of your code base the
other reason I have this problem reading
code bases and trying to track down
where functionality actually lives is
because object-oriented design tends to
fracture functionality in our code it
tends to take what otherwise could be
relatively self-contained code and split
it up into many separate methods across
many separate classes typically often in
many separate files for God's sake this
fracturing is accepted because of an
ideology about encapsulation and this
notion of classes and methods properly
having so-called single responsibilities
and our certainly valid arguments for
that idea certainly it is much easier to
get a small short function correct and
to get a large sprawling function
correct but the important question is
that in splitting our code under too
many little small methods and too many
separate classes are we actually
decreasing the total complexity of our
program or just displacing the
complexity just merely spreading it
around in either case there is this
attendant trade-off we're making whereby
splitting up larger units of code into
many smaller ones
we're greatly increasing is the
so-called surface area of our code where
I come along and I look at your code
base and try and get a foothold and
everything split up into these tiny
little units these tiny little packets
of code reading this kind of code often
feels frustrating in the same way it can
be frustrating to eat a bunch of little
candies that are all individually
wrapped and when all your methods are
really really short you end up having to
jump all around the code to find any
line of logic a lot of business that
otherwise could be neatly sequentially
expressed in longer methods gets
artificially split up so it feels like
you've taken a neatly sorted deck of
cards and thrown them into the air so
you can play 52 card pickup
so if you're not going to be writing
object-oriented code what are you going
to be doing instead you're going to be
writing procedural code but what does
that look like well as I mentioned at
the beginning this doesn't necessarily
mean you need to avoid classes entirely
if you have a language like Python or
C++ where you have both straight
functions and also classes there are
some cases where the association between
your data types and certain functions is
really really strong that it fits some
organizational purposes to just
explicitly associate them together but
making those functions methods of that
type the most obvious example would be
ADT so abstract data types things like
queues and lists and so forth the key
thing to keep in mind however is at the
moment you start hemming and hawing
about whether this particular function
really has a primary association with
that data type that should be the moment
you say screw it will make it just a
plain function because it turns out that
most things we do in code tend to be
cross-cutting concerns they don't have
necessarily special obvious
relationships with particular data types
they might concern more than one data
type and that's why you should generally
prefer functions so you don't have to
play this silly game of matchmaking
functions two data types so we're going
to be writing our code primarily out of
plain functions and we're not going to
attempt to encapsulate the state of our
program at a fine-grained level because
it doesn't work however shared state is
still a problem and if we're not careful
it can get out of hand we can't totally
solve the problem unless we do a pure
functional programming but short of that
there are broad guidelines we can follow
to mitigate the problem first off when
in doubt parameterize this means that
rather than passing data to functions
through global variables you should
instead make that data and explicit
parameter of the function so it has to
get explicitly passed in as much as
possible we want data access in our
program to flow through the Col graph so
any time you're tempted to pass data to
a function through a global because it
seems more efficient or maybe just more
convenient you should give that a strong
reconsideration secondly whatever
Global's you do end up with in your
program it can be slightly helpful to
group them logically into data types
even if this means you effectively have
a data type with one instance in your
whole program this little trick can
often make your code seem just a little
bit more organized in a sense you're
just using data types of way to create
tiny little sub namespaces but if you do
a good job logically grouping your
Global's this way as a side benefit this
can complement rule number
because now you can more conveniently
pass this global state to functions by a
bundling your data together in two types
you typically cut down on the number of
parameters which functions have to take
though do be careful there is an art to
how you logically group things together
the third guideline is to
opportunistically favor pure functions
even if you're not explicitly working in
a functional style or working in a
functional language if you see an
opportunity to make a function pure it's
generally good strategy to take that
opportunity again pure functions tend to
come in at efficiency cost but the
brilliant thing about pure functions is
that they're the only truly
self-contained unit of code when I'm
reading and writing a pure function I
don't have to think about anything else
I can just consider that function
entirely unto itself therefore they tend
to be easier to understand and to make
correct the fourth guideline is that we
actually should try to encapsulate our
code only in a very loose general sense
at the level of namespaces packages
modules whatever your language has so
when I'm working in go Lang for example
I think of each package is having its
own private state and then a public
interface I find that encapsulation at
this coarse grain level tends to work
because you're typically dealing with
much larger units of code than the
supposedly ideal classes of
object-oriented programming the typical
golang program is going to have not that
many packages maybe like ten at the high
end and structuring I'm your handful of
elements into hierarchy of encapsulation
is reasonably doable when it turns out
during development that oh wait I have
some cross-cutting concern of my
packages and so we're going to violate
this perfect hierarchy of encapsulation
again it's not such a big deal because
you're dealing with a relatively small
group of objects all the basic problems
of encapsulation are still there is just
that the coarse-grained macro level the
problems are reasonably manageable the
last guideline is that you shouldn't be
scared of long functions for a long time
now program and students have been
advised to when in doubt chop their code
into smaller and smaller functions but
doing this has significant costs there
are trade-offs it turns out that most
programs have these key sections where
most of what the code is doing is a long
laundry list of stuff and what we're
told to do in these scenarios is write
functions like this where all the
business has been extracted out to
separate functions the problem with
doing this pervasively is that what was
naturally a logical sequence of code and
was
otherwise written in sequence top to
bottom is now spread and out of order
throughout your codebase obviously in
cases where the business extracted to a
separate function is something that you
want to call in multiple places that's a
very good reason to have a function but
if all these functions were just called
in this one place I would generally
prefer looking at code where the
business of those functions is just done
in line and if you want high-level
documentation of what's going on in my
func here then you just put what I would
call a section comment denoting what
each section of the code does in this
arrangement the sequence of the business
is totally clear and when I'm browsing
the whole codebase when I'm looking
outside this function there's less
clutter because there are now fewer
functions have to look at and wonder
well hey where is that cold I wonder
what that thing does it also has
advantage of letting us avoid having to
named functions naming stuff is really
important in code but is really really
hard to do well and in general I find it
preferable if we can avoid naming
entities as much as possible in this
arrangement we don't have to think hard
about what to call these functions we
can just have a comment line and have a
full English sentence which generally is
better at conveying accurate meaning and
also is simply easier to write if for
whatever reason it doesn't seem adequate
to simply comment a section rather than
extract it to a separate function the
next best thing is to make it a private
function a nested function such that
it's clear this function is not called
anywhere else it's only cold within this
function in this arrangement I as a
reader of your code coming from the
outside I'm still presented with a
smaller surface area fewer entities in
the code and so it's just easier for me
to get a foothold now when you do write
functions which are hundreds if not
thousands of lines long you still should
keep in mind general guidelines about
code readability basic things like not
straying too far from the left margin
for too far or for too long you know you
don't want to have code that's indented
in eight levels because it gets really
obnoxious to scrolling up and down code
if you have to scroll over for one thing
and also it tends to just imply there's
a lot of busy logic in this part of code
and it gets confusing so likewise you
also need to look out for parts of
functions where the logics is getting
too complex the first thing to do is of
course to try and simplify your logic
but failing that there are going to
cases where hey we should just split
this off into a separate function so
it's more neatly self-contained
complexity the other concern with longer
functions is that as your function gets
longer and longer you tend to accrue
more and more local variables
so what you want to do is hopefully a
language allows us you want to try and
constrain the scope of the local
variables so that they don't exist for
the full duration of the function but
rather for subsections this way either
reader of your code when they scan up
and down the function I don't have to
think about all the variables for the
whole duration of the function the way
this is done the most curly brace
languages is you can just introduce a
new sub scope with curly braces so here
for example this integer X variable only
exists within these curly braces when
you have subsections of a function which
you are commenting it's generally a good
idea to when in doubt enclose them in
curly braces this gives readers of the
function and assurance that variables
from the preceding sections don't fall
through to the following sections and so
in later sections we don't have to think
about the variables that were used above
where possible the even better thing to
do is to enclose these local scopes in
their own anonymous function that's then
just immediately called an advantage
here within the nested function is that
it's not just its own sub scope but also
within this anonymous function it's
guaranteed then any return is not going
to return out of the enclosing function
it'll return just out of this enclosed
function and so we have a stronger
guarantee that the logic of this
subsection is self-contained from the
enclosing function unfortunately what I
often really want
when creating subsections of longer
functions is a feature that doesn't
exist in any language I know of it's an
idea I've only seen in one other place
it was Jonathan Blow and this talks
about his argument language these making
and the idea is that we want something
like an anonymous function which doesn't
see anything of its enclosing scope the
virtue of extracting a section of code
out to a truly separate function is that
everything that comes into the function
has to be explicitly passed to a
parameter it would be great if we could
write inline anonymous functions with
the same virtue specifically what I
would propose is imagine we had a
reserved word use that introduces a
block and in the header of the eu's we
list variables from the enclosing scope
which we want to be accessible in this
block but otherwise anything from the
enclosing scope would not be visible
these listed variables however would
really actually be copies of those
variables so if you assign to X or Y
here in the scope you're assigning to x
and y the local variables of this use
block not to X and y of the enclosing
scope which is the effect you get with a
truly separate function right you assign
to the parameters of
function you're not modifying what was
passed to the function you're just
modifying those local variables that's
the same thing we want in this use block
furthermore a use block should itself
return values so you use return inside
the use block and it doesn't return from
the enclosing function it returns from
the use itself that uses an expression
and so we can return values from this
use and assignment to this variable a so
in effect we'd have this block of code
which is as neatly self-contained as a
separate function however it is written
in line and so it's very very clear that
oh this is a piece of code that's only
used in this one place you don't have to
go look for it elsewhere and also we
don't even have to give it a name
instead we can just put a section
comment header before the use block and
that is generally much better for
containing the actual intent of this
block of code if later down the line we
decide that this block of code actually
should be extracted to tone proper
function that's a very easy thing to do
you can have an editor convenience that
does that for you automatically it's
already clear what the parameters and
the arguments should be all the
programmer would have to do is provide a
name for the new function so anyway it
would be nice if language has had this
feature unfortunately I don't know of
anyone that does but regardless you
shouldn't be so scared of long functions
they actually have their place in most
code bases at the very
I hope I can get you to try procedural
programming it doesn't really matter
what language you're in if you're in
Java or C sharp you can write the
procedural code you can break the rules
but if you've ever felt any of the
paralysis that I felt attempting to do
object oriented programming properly to
square the circle I think you'll find
abandoning all those ideas and just
reverting the procedural code to be a
liberating experience I can tell you
from personal experience that having
read these books that you don't need to
read them they don't have answers
they're not going to square the circle
and you're going to waste productive
years of your life trying to live up to
their ideals I'm not saying there's
nothing to these ideas there are bits
and pieces that have value test-driven
development for example has some
interesting ideas there's value in
testing but that's part of the problem
is that kernels of good ideas have been
taken to holistic extremes in a way that
I think has been disastrous for the
industry and certainly for programming
education there are very few solid
holistic answers about how we should
write code we'd all be better off if we
stopped chasing that Chamara
you
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.