00:00:19.800
alright guys i'm an invertible a I work
00:00:24.909
in company name equal experts which is
00:00:27.880
in Pune India and I'm going to talk
00:00:30.909
about qualities and principles in to be
00:00:33.239
so so this topic is about design
00:00:40.210
principles which I realized helped me to
00:00:42.820
improve my code and ultimately right
00:00:47.289
good object-oriented code which is
00:00:49.530
extensible and like reusable
00:01:00.170
so all of us are software developers so
00:01:03.290
initially when we write our code or
00:01:05.990
application it is all good
00:01:08.570
version 1 dot o is very good there are
00:01:12.140
no issues but after some time your
00:01:17.000
application becomes like this with off
00:01:19.220
changes you keep changing your code you
00:01:22.340
keep modifying your code because of
00:01:24.409
client requests and that makes your code
00:01:28.700
bad so your application will change and
00:01:37.060
it will become messy and developers will
00:01:40.940
hate to work on it it's very it will
00:01:43.789
become very difficult to actually go and
00:01:47.149
add features though mostly I have seen
00:01:49.729
this happening in most of the project so
00:01:52.429
why that happened it happened because of
00:01:54.399
bad design so if your application does
00:01:58.369
not have good design if it doesn't have
00:02:01.479
like good object-oriented code it will
00:02:05.270
be very difficult to add like new
00:02:08.660
features to it software time it becomes
00:02:13.190
bad so writing model code doesn't mean
00:02:15.709
writing good design so most of the Ruby
00:02:21.530
programmer actually follow Ruby Adams
00:02:23.600
some of the model rarity concepts so
00:02:26.450
just because you follow dry or TDD
00:02:32.769
doesn't mean you are following good
00:02:37.489
design so good design is about managing
00:02:40.670
dependencies Ruby's object-oriented
00:02:43.850
programming language so everything is
00:02:45.680
object into B so whatever you write are
00:02:48.380
nothing but objects and how those
00:02:50.180
objects are interacting with each other
00:02:52.299
that makes a good design and that will
00:02:56.030
make your code extensible and like ready
00:02:59.480
for change so these are this in this
00:03:04.549
diagram is dependent on X Y Z so
00:03:07.310
exercise it depend on M
00:03:09.770
this subclass of T so all these are
00:03:12.510
dependencies and if you don't manage
00:03:14.400
these dependencies well in your
00:03:15.930
application
00:03:16.530
it is going to hurt in future so
00:03:19.380
unmanned managed dependencies are
00:03:20.970
killing your application and a good
00:03:23.670
design might save you so what are smells
00:03:28.140
of bad design first is rigid rigid means
00:03:30.450
your application is difficult to change
00:03:32.600
one change is causing too many other
00:03:35.340
changes in your system if that's the
00:03:37.380
case it's rigid second is fragile
00:03:39.750
fragile means your application is easily
00:03:42.180
breakable so if you change one part like
00:03:47.130
if you change controller and suddenly
00:03:48.540
worker is breaking so something is like
00:03:51.090
messed up so that's fragile design
00:03:54.050
immobile so whatever you write should be
00:03:56.940
reusable if you are writing code which
00:03:58.560
is not reducible then it's not of any
00:04:01.140
use so if your code is hopelessly
00:04:04.230
entangled with each other that makes
00:04:06.540
your application immobile and viscous so
00:04:10.080
viscous means you probably have followed
00:04:13.020
good design but it's very easy to add
00:04:16.980
hacks then actually follow good design
00:04:18.750
if that's the case then that means your
00:04:21.090
application is viscous so initially it
00:04:26.580
was good so like whenever we write a
00:04:29.580
patient for the first time it was good
00:04:31.410
but after many changes after like new
00:04:35.100
changes new requirements it becomes bad
00:04:37.290
and that's a pattern actually that
00:04:38.550
happens many times so change is killed
00:04:40.830
it so software development is not a game
00:04:43.530
of Jenga right we don't keep adding
00:04:45.270
features so if we keep adding features
00:04:47.910
without actually thinking about design
00:04:50.070
it will work for like some time but
00:04:52.980
after some time it will become very
00:04:55.230
difficult to manage that application and
00:04:56.790
in enterprise world this is a pretty
00:04:59.040
common pattern so so why solid So Solid
00:05:03.650
helps us to write loosely coupled highly
00:05:07.770
cohesive easily composable context
00:05:10.740
independent reusable easily testable
00:05:13.890
code so ultimately it makes your code
00:05:18.270
easy to maintain and extend over time so
00:05:22.530
Robert
00:05:23.430
my teen who is famous as Uncle Bob has
00:05:27.330
written this paper in early
00:05:29.670
two-thousands design principles and
00:05:31.440
design patterns which mentions about
00:05:33.240
dispensable and also a michael feathers
00:05:36.750
coined this term solid so s means single
00:05:41.880
responsibility o means open closed
00:05:44.340
principle L means Liskov substitution
00:05:46.920
principle
00:05:47.760
I mean Enterprise Solution principle
00:05:50.300
demas dependency inversion principle
00:05:52.520
let's look at these principles in detail
00:05:56.060
first is single responsibility so this
00:06:00.840
principle says a class should have a
00:06:02.670
single purpose class should serve a
00:06:05.400
single purpose there should not be more
00:06:06.990
than one reason for a class to change if
00:06:09.120
there are multiple like behaviors that
00:06:12.120
you have wrapped in a class that means
00:06:14.130
it's not single responsible the ways of
00:06:17.880
achieving this principle are revealing
00:06:19.590
intent like find out what is the intent
00:06:23.310
of your code renewal rename the
00:06:25.530
variables in whom the method names
00:06:28.230
rename the introduced constants and
00:06:30.450
extract methods into other methods
00:06:32.750
extract behavior to other classes
00:06:35.700
extract methods to other classes if you
00:06:38.460
do that it will make you like it will
00:06:42.750
induce new classes and that will have
00:06:44.520
single responsibility so far length saw
00:06:47.370
a single response to decode generates
00:06:49.860
highly cozy code and removes the
00:06:52.410
mobility smell so let's say our client
00:06:56.130
asked us to implement filter server
00:06:58.020
application so let's see how we can
00:07:00.480
apply for single responsive principle
00:07:03.090
there
00:07:19.700
so a developer could go and write like
00:07:26.930
these methods so food is our application
00:07:28.490
basically fetches food from a feed URL
00:07:30.440
parses that food and serves the feed to
00:07:32.960
database so one class can actually have
00:07:35.600
these three methods a normal developer
00:07:37.520
could go and write code like this this
00:07:39.470
will work but this class is not
00:07:41.240
following single response and principle
00:07:42.740
so to our choosing the responsible in
00:07:44.690
Sippel we could really factor like this
00:07:46.730
so we could extract methods into
00:07:48.470
different classes which are single
00:07:50.810
responsible so feed fetcher will fetch
00:07:53.090
feed RSS parcel will parse the RSS feed
00:07:56.990
and feed server will save the field so
00:08:00.560
if you do that we can reuse this classes
00:08:04.010
from other parts of your code and your
00:08:07.550
code will become cohesive and also
00:08:10.030
immobility smell will go away so this is
00:08:12.890
how we are chuh single responsive
00:08:14.630
principle so next principle is open
00:08:24.020
closed principle as you see in this
00:08:25.940
image to wear a coat you don't have to
00:08:28.730
do heart surgery
00:08:29.710
so the principle says the same software
00:08:33.260
entities classes model method should be
00:08:36.050
open for extension but close for
00:08:37.460
motivations is it practically possible
00:08:40.280
to write such code which is open for
00:08:42.170
education but practically sorry closed
00:08:44.120
for moderation
00:08:55.960
it can be achieved using inheritance and
00:08:58.610
composition and if your code has lots of
00:09:03.110
fulfills cases or long switch cases that
00:09:05.150
means there is a chance you do this to
00:09:07.370
be dispensable that's the example for
00:09:12.290
this so now clients want to like
00:09:21.250
introduce atom parsing so previously
00:09:24.920
used to it used to do RSS parsing now it
00:09:28.220
is also parsing RSS so it is like a
00:09:32.180
developer could go and add he fills case
00:09:35.270
and just delegate the atom parsing to
00:09:38.690
atom parser but this cell field has now
00:09:42.380
if Phil's case and that is changing
00:09:44.960
behavior so tomorrow if our clients
00:09:47.660
wants another type of field to be parsed
00:09:49.390
he has to go and modify this code so
00:09:52.040
this method is not open for extension
00:09:53.810
and also not close for more modification
00:09:56.930
so to achieve open closed principle what
00:09:59.690
we could do is that so we could abstract
00:10:15.590
this behavior of if-else is we could
00:10:18.770
introduce a parcel abstraction and that
00:10:21.080
parse our abstraction we could just in
00:10:24.020
Ruby we don't have to add that parser
00:10:25.790
class because Ruby's duck type but now
00:10:30.050
we have RSS parser and atom parser and
00:10:32.900
we can just call this like we can just
00:10:37.250
pass this parcel to the our sale field
00:10:40.370
class so now our method is open for
00:10:43.610
extension and close for motivation we
00:10:45.440
can just add another type of parser if
00:10:48.350
required and pass it puts a field and
00:10:50.510
that way we can achieve open post
00:10:53.180
principle
00:11:03.029
basically you have to like if there is
00:11:06.970
branching you have to replace that with
00:11:08.740
delegation you have to inject changing
00:11:13.029
dealer don't have changing beer in your
00:11:15.279
class just inject that from outside and
00:11:18.270
wrap behavior with abstraction so if
00:11:21.610
there is if your there are different
00:11:25.060
types of ApS for the dependencies you
00:11:27.550
could actually wrap that dependencies
00:11:29.440
into a one abstraction and then pass
00:11:31.690
that dependency to the user of that
00:11:35.470
dependency so that's how we achieve on
00:11:38.350
post principle so we saw the code
00:11:44.410
example and this is how we are to
00:11:46.540
abstraction abstraction with parser and
00:11:49.470
followed open-closed principle okay
00:11:52.899
let's see next principle which is Liskov
00:11:54.880
substitution principle as this image
00:11:57.760
shows if it looks like that
00:12:00.190
quacks like that but needs back to this
00:12:02.470
it might be a wrong extraction this is
00:12:06.880
very different principle actually this
00:12:09.970
was written by Lister Barbara and there
00:12:15.579
is a rule for this people firstly the
00:12:18.700
subtype must be substituted for their
00:12:20.500
base types and this rule is like that
00:12:24.190
like this let qfx be a property provable
00:12:26.800
about objects X of type T then U of Y
00:12:29.649
should be true for objects Y of type s
00:12:33.399
where s is subtype of T basically
00:12:37.079
subclasses should not modify the Europe
00:12:40.029
of their parent class this line also
00:12:42.850
tells more about this principle if a
00:12:45.160
piece of client code works for our type
00:12:47.050
then it must work for all Arab or
00:12:49.839
variant types a new type new subtype
00:12:53.079
should not screw up client code rules
00:12:58.240
implement inheritance based on behavior
00:13:01.029
do not wanna let be R of your parent
00:13:05.350
class do not do less than your parent
00:13:07.630
class it's okay to extend behavior but
00:13:10.180
it's not okay to actually
00:13:12.610
stop the beer of your parent class and
00:13:15.310
also lists kibarim mentions about pee
00:13:19.300
and postconditions rule we will see what
00:13:21.579
are those instead of our RSS parser
00:13:32.829
example we will take this classical
00:13:34.930
example for Liskov substitution
00:13:37.170
principle suppose our application using
00:13:41.610
instances of this rectangle class so
00:13:44.290
rectangle has width and height and
00:13:46.440
rectangle also has method called area so
00:13:49.930
this is what you find it's like there
00:13:53.019
are thousands of inches of rectangle
00:13:54.490
linear application and now suddenly our
00:13:57.430
client says I want to do this square so
00:14:00.209
a developer could thing a square is
00:14:03.339
perfect triangle and he could into the
00:14:06.790
square like this where he could just
00:14:08.980
override like he could just pass side
00:14:12.640
and instead of width and height because
00:14:15.790
square does not have good tonight and
00:14:17.079
square this perfect rectangle so he just
00:14:20.529
changes initialize method to pass side
00:14:22.089
and this could work fine but there is a
00:14:26.980
high chance that some other developer
00:14:28.600
could override this height method and if
00:14:33.250
you see right square is square will
00:14:35.920
return areas hundred normally but if
00:14:39.100
somebody overrides this height it will
00:14:41.230
return 300 so that's that's breaking
00:14:44.560
Liskov substitution principle so you
00:14:46.329
should follow Liskov substitution
00:14:47.170
principle for better cool let's see what
00:14:51.459
are pre and post conditions here we will
00:14:56.709
take example of base calculator base
00:14:59.079
calculator actually calculates past
00:15:03.370
input the bearer of best class is that
00:15:06.630
it the input should be greater than 0
00:15:10.750
and less than 20 so a valid subclass can
00:15:18.820
actually so the rule is pre conditions
00:15:23.410
cannot be strengthened in a subclass so
00:15:26.380
surplus can actually weaken the
00:15:29.380
preconditions but it cannot strengthen
00:15:32.110
precondition so let's see another
00:15:34.440
surplus so here you can see this is
00:15:39.090
weakening precondition thats allowed but
00:15:41.380
if it starts standing preconditions it's
00:15:44.680
breaking Liskov substitution principle
00:15:45.850
so whenever you write subclasses you
00:15:48.070
should take care that you are actually
00:15:50.620
not engineering the preconditions so
00:15:53.650
that's how we are chuh precondition rule
00:15:57.120
is not by not breaking the so by not
00:16:10.000
breaking the behavior of parent class so
00:16:12.580
this rule is about boost conditions it
00:16:15.970
says that post conditions cannot be
00:16:17.470
weakened in surplus so we have best
00:16:20.410
calculator the contact is it will always
00:16:23.230
return positive numbers so currently a
00:16:25.720
base class is returning positive numbers
00:16:27.280
but if you write a surplus which will
00:16:30.930
starts returning any kind of number
00:16:34.840
which is passed
00:16:35.470
suppose if you first when you are doing
00:16:36.850
the per if you start returning that if
00:16:38.860
you're breaking count contract and you
00:16:41.860
are weakening your post conditions so if
00:16:44.260
that's the case it means that you're
00:16:47.470
breaking Liskov substitution principle
00:16:48.720
so so I I gave this classic examples
00:16:53.650
because in the normal way this principle
00:16:57.010
is hard to explain in the regular
00:16:58.990
application but if you follow these
00:17:00.400
rules it is easy to for forest Liskov
00:17:04.360
substitution principle
00:17:17.740
okay so next principle is Enterprise
00:17:21.279
decoration principle right there is a
00:17:25.360
USB port there are use report and here
00:17:28.299
there is a USB so this principle says
00:17:31.570
that many clients specific interfaces
00:17:35.289
are better than one general purpose
00:17:36.669
interface so it's better to have a
00:17:39.159
client specific interface separate
00:17:41.890
client specific class so you know you
00:17:44.409
don't have interface we have models and
00:17:46.390
classes so we can say that many client
00:17:49.210
specific models are better than one
00:17:51.010
general purpose model or class client
00:17:56.500
should not be forced to depend on method
00:17:59.020
that they do not use so so following
00:18:04.960
this principle helps us to write a
00:18:06.640
highly cohesive and highly corrosive
00:18:09.159
code and removes immobility smell let's
00:18:12.909
see like two examples which will convey
00:18:17.020
this principle
00:18:27.940
so we have a common model TV which has
00:18:31.730
on of select channel up-down record and
00:18:34.640
play methods and we have the HDTV on
00:18:39.590
normal TV so lttb includes the TV model
00:18:42.050
which is fine and normal TV includes
00:18:44.570
this TV model but normal TV doesn't need
00:18:47.840
the record and play methods so what we
00:18:50.240
could do is that we could overwrite
00:18:51.620
these methods and say okay those are
00:18:53.690
disabled so like this works but it's
00:18:59.120
working interface aggression principle
00:19:00.740
so you should segregate your methods
00:19:02.960
into two different models actually
00:19:04.850
instead of common TV model you could add
00:19:07.820
a model limb DVR and a model TV so DVR
00:19:12.800
model will have record and play methods
00:19:14.870
and TV model will have other methods
00:19:17.990
other than techadon play which are
00:19:20.390
common and HDTV model will include this
00:19:25.390
HDTV class will include these two models
00:19:27.920
and normal TV class will include just TV
00:19:31.490
model so that's how we achieve interface
00:19:33.950
aggression with models let's see another
00:19:37.070
example where it's with classes so let's
00:19:42.290
say we have a class called car car has
00:19:46.730
theme these three methods opened or
00:19:49.030
FATCA change engine driver is making use
00:19:52.970
of only two methods open door and start
00:19:54.950
car and mechanical mechanic will use
00:19:58.930
change engine so the same object of the
00:20:03.980
class is shared between two different
00:20:05.570
clients so instead of right so this is
00:20:09.650
braking interface aggression principle
00:20:10.790
so you should have two different classes
00:20:13.630
like this
00:20:27.640
now a driver is making use of car object
00:20:31.429
which is fine because the object now has
00:20:32.990
only two methods which a driver will use
00:20:36.710
and mechanic doesn't need this car
00:20:39.289
object it can have separate class which
00:20:41.690
it which is carry internals and that has
00:20:44.870
this change engine method so this rule
00:20:48.860
is like seems okay why we should do this
00:20:52.100
but this actually makes your code highly
00:20:54.710
cohesive and immobile and extensible oh
00:20:58.490
for the future okay next principle which
00:21:08.210
is last principle which is dependency
00:21:10.520
inversion so as the image shows instead
00:21:14.630
of connecting wire directly we we are
00:21:17.120
using switch and the principal says
00:21:21.169
depend on abstraction do not depend on
00:21:24.169
conclusions there is another definition
00:21:31.460
of this principle which is more
00:21:33.559
theoretic higher level models should not
00:21:36.740
depend on the low level models both
00:21:39.470
should depend on abstractions
00:21:41.020
abstraction should not depend on details
00:21:43.190
details should depend on abstractions
00:21:45.409
like this seems very difficult to
00:21:50.360
understand but let's see how this is
00:21:52.399
achieved with a classic example so let's
00:21:57.020
say there is a program which is up here
00:21:58.779
which is reading from keyboard and
00:22:01.159
writing to printer so a copier program
00:22:05.120
could be written like this let's see
00:22:15.100
which has now hardcore dependencies
00:22:17.650
keyboard and printer so this works but
00:22:20.740
to follow dependency inversion principle
00:22:27.390
so then name of the principle is
00:22:30.850
dependency inversion right so how to
00:22:33.100
invert dependencies currently in
00:22:34.960
dependency direction is on down
00:22:37.030
downwards direction so to revert
00:22:39.820
dependencies so tomorrow if you want to
00:22:45.400
use disk instead of printer it's
00:22:48.100
impossible with this because you have to
00:22:49.810
change the code we can achieve that with
00:22:52.180
this dependence like inverted
00:22:55.000
dependencies we could introduce
00:22:57.630
abstraction copier should depend on
00:23:01.720
these two abstractions with which is
00:23:03.370
first is reader abstraction second is
00:23:05.710
writer abstraction and as the principles
00:23:09.670
says high level model should not depend
00:23:12.070
on Lowell Lowell models but you depend
00:23:13.900
on objections so you can see both are
00:23:15.910
now depending on these two abstractions
00:23:18.010
reader application writer abstraction
00:23:19.780
and abstraction should not depend on
00:23:22.210
details details should depend on
00:23:23.410
objections so that is also attune so
00:23:26.130
this is how we invert dependencies and a
00:23:30.570
common like we can implement this using
00:23:35.320
dependency injection a common pattern to
00:23:37.780
do but this can be very like abstract
00:23:41.470
like you can have common contact which
00:23:45.070
is common abstraction in like rest
00:23:48.310
services we write contract right so we
00:23:51.310
are not depend on actually
00:23:52.630
implementation we mostly have contacts
00:23:55.390
there so this is pretty abstract you
00:23:59.710
know like principle but if you follow
00:24:02.800
this principle you again make your code
00:24:04.990
very clean and easy
00:24:16.240
so let's see that same example where now
00:24:24.790
this code shows it has used these
00:24:26.770
abstractions and tomorrow we can change
00:24:30.160
printer to disk so common spells of this
00:24:39.810
principal are a new keyword if you see
00:24:42.250
new keyword in your code it means that
00:24:44.080
there is a chance you can do like
00:24:46.900
dependency inversion and directly static
00:24:50.860
or class method calls if you have that
00:24:53.140
that that also is breaking this
00:24:55.330
principle so what what does applying
00:24:58.720
solid principles lead it it converts you
00:25:01.810
a rigid fragile and scary code to
00:25:03.660
flexible robust and curly code and I
00:25:07.930
recently came across this to it which
00:25:10.450
says you cannot teach software design
00:25:12.280
but this is wrong
00:25:15.070
actually by learning these principles I
00:25:17.530
have one example to share so in my
00:25:19.960
company a fire descended say had join
00:25:22.570
and they were writing they were solving
00:25:25.030
some problems using object-oriented code
00:25:27.820
but that code was not good enough since
00:25:31.450
they since the day they learn about this
00:25:33.370
solid principles they the code they
00:25:35.980
wrote and therefore tried to follow
00:25:37.840
these principles it is not always
00:25:40.300
possible to apply all five principles
00:25:42.940
but if you follow at least four
00:25:44.320
principles your code is good enough to
00:25:46.390
go to production and ultimately it
00:25:50.260
becomes extensible and reusable so so
00:25:55.510
the TDD is not enough like doing TDD
00:25:57.720
people say it helps to your design but
00:26:00.930
it not it does not and drys also not
00:26:04.210
enough if you just follow try it's not
00:26:06.580
that you are writing it might be like
00:26:09.400
just model code but it's not about
00:26:11.020
design so design because you expect your
00:26:13.480
application to succeed because whatever
00:26:15.880
we write today if he succeeds we have to
00:26:18.640
change the code and if your change is
00:26:20.230
not ready for if a code is not ready for
00:26:23.740
change then you have problems also if it
00:26:27.100
is
00:26:28.010
having bad design it is also bad for the
00:26:30.410
feature of the application so do design
00:26:35.179
and design patterns so design patterns
00:26:39.860
are reusable solutions to commonly
00:26:41.510
occurring problems so if you follow
00:26:46.010
design patterns blindly it's a problem
00:26:47.929
but if you followed design principles
00:26:50.090
blindly I think it will definitely help
00:26:52.070
so I used to like I read about design
00:26:56.390
patterns so long time back and I used to
00:26:57.980
forward
00:26:58.580
apply design patterns but it was
00:27:01.000
complicating my code but further in
00:27:03.230
design principles never complicated my
00:27:04.970
pole it actually helped to write code
00:27:07.370
with better design so finally as in the
00:27:10.400
last studies by constantin abstraction
00:27:15.320
is the key you have to abstract things
00:27:18.340
you know all the principles somewhere
00:27:21.950
there abstraction is there and if you
00:27:27.140
abstract the things out it will
00:27:29.929
automatically follow these principles so
00:27:33.100
follow solid principles thank you I do
00:27:41.690
recommend reading this book by sandy
00:27:43.730
mates
00:27:44.059
my talk is inspired from her talk so and
00:27:47.240
also thoughtbot has this weekly
00:27:49.460
attrition like when on screen has this
00:27:52.130
discussed about this principles in
00:27:54.200
detail and uncle bob has this site
00:27:58.280
called clean coders where he also
00:27:59.809
discusses about these principles so a
00:28:01.760
Ruby programmer we always believe in
00:28:04.070
that typing on all the things but I
00:28:05.809
think if you are working as application
00:28:07.520
developer big appellation we follow
00:28:09.350
these principles will help your future
00:28:12.610
it will make you happy developer yeah
00:28:19.130
thanks
00:28:21.020
so we're running a little short on time
00:28:22.990
but maybe you can take one question
00:28:30.880
think thanks for your talking though all
00:28:34.820
these principles sound great my question
00:28:38.270
is which one of these principles do I
00:28:40.760
need to apply to prove that rainbows are
00:28:43.130
real all of them okay so thanks a nail
00:28:50.360
again okay thanks