All language subtitles for Object-Oriented Programming is Bad_EN

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

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.