Episode Transcript
Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Peter (00:02):
What's up, everybody?
Welcome to another episode of
the podcast. This week, we aregonna be talking about a
follow-up here to a blog post byGeoff. He was talking about
swift data and separation ofconcerns came into play. And we
thought, you know what?
This will make a good episode.So so let's start by saying,
Geoff, how are you doing, buddy?How how's your week been?
Geoff (00:23):
I'm doing great. Little
behind the scenes. We are
actually recording this episode,like, three days after the last
episode. So, there actuallyhasn't been a whole lot of time
for anything to happen.
Peter (00:34):
Yeah. Spoiler alert.
Right. Yeah. Yeah.
Nothing got better in threedays. Right? That's that's
basically Alright. So let's getinto this. So you you did a blog
post that you put out there.
And, of course, folks, we'll puta a link in the show notes. And,
you know, for those who don'tknow what separations or
concerns are, I think this isgonna be interesting and
(00:55):
probably spark someconversations, right, based on
what I saw in the Discord. And,again, we'll put a link in the
Dev links. So go for it, Geoff.
Geoff (01:02):
So, yeah, this all came
about. The blog post was kind of
heavily demanded by people in,the Discord because I had spent
a rather decent amount of timerailing against the query
property wrapper in Swift data.And people were really like,
hey. You know, if you hatequeries so much, like, why do
(01:25):
you hate queries so much?Explain why you hate it, why you
think it's bad, yada yada yada.
And so out of that came a blogpost that was essentially, you
know, a little over the topopinionated, but, you know,
that's that's how you
Peter (01:40):
That's what we do.
Geoff (01:41):
Blog these days. Right?
Peter (01:42):
Yeah. That's what makes
us people tune in for for us to
be opinionated.
Geoff (01:46):
They don't care about the
truth. Exactly. Yeah. Basically
saying, hey, don't use the queryproperty wrapper in Swift data
because it makes your code morefragile. It makes your code less
flexible, and it's easier towork with Swift data if you're
not using it.
And the reason for that is theidea of this separation of
(02:09):
concerns. And so I think whatwe're gonna do is we're gonna
we're gonna pull out the bits ofthat that are generic, the bits
of that blog post that apply nomatter what language you use, no
matter what frameworks you'reusing, and really kinda talk
about, like, why does thismatter, how can you implement
it, and what are the benefitsyou get from implementing
something like this?
Peter (02:30):
Yeah. Now, first of all,
I do wanna say, right, I use
that query in my Swift data. Notthat I've extensively used swift
data, and I've not had aproblem. So, you know, I guess
I'll I'll be on the other sideof that.
Geoff (02:42):
Shipped an app with it?
Peter (02:44):
That was a good question,
actually, because I was thinking
about that today. And
Geoff (02:48):
Have you actually
finished shipping?
Peter (02:49):
Have did I did I I've
this came up actually at the
weekend because someone asked meabout JobFinder tracker. And I
JobFinder tracker does actuallyuse some swift data. So, yes, I
guess the answer is yes. I have.And Good.
And I have successfully sold tosomeone, some peoples. So I
guess it's okay.
Geoff (03:09):
Yeah. Yeah. No. I mean,
if it's not like if you are
using query right now and youyou you're not having any
problems with it, you gotta goout and tear it all pieces right
now. But, I I definitely thinkit encourages some bad
behaviors, and I think it shouldmore or less be avoided even
though Apple really kinda triesto push it because it makes
(03:31):
their code look pretty on WWDCslides.
Peter (03:34):
It's all about looking
pretty.
Geoff (03:35):
Yeah. I think what I'm
gonna do here on this episode is
kind of provide, like, a asample example, one that I can
discuss in audio form, and kindof work through and explain what
you might have done before, whythis can cause problems, and how
you can avoid these problems byusing the principle of
(03:56):
separation of concerns, and someof the benefits that you're
gonna get through doing that.For this example, let's imagine
you've got your your standard,default, what what's a project
that you're gonna build, andwe're gonna talk about a task
list app. And in this task listapp, you are syncing this with
(04:16):
some kind of remote API. Couldbe a server, could be iCloud,
could be whatever.
We don't care. Now, what youwould do, like, kinda the the
the simplest, moststraightforward approach that
you're gonna do, is you're gonnawrite some kind of type that
represents, say, your task. Andwith that type, you're gonna
(04:38):
say, okay, in Swift, you mightmake it codable in, Android
sorry. Kotlin. What's thelanguage that that thing's
called?
In Kotlin, you might have the,like, Kotlin serialization and
mark everything with theserializable, encode and decode
them from from your API. Andthen you might use that same
(05:00):
type directly in your view.You're gonna say, okay. Well,
I've got a list of tasks. I'mjust gonna take these tasks that
I got from the API, and I'm justgonna put them in a list.
And that works great once. Youkinda just go fetch that data
from the API. Here it is.Display it in the list. Not a
problem.
Well, imagine that you, as adeveloper, don't control the
(05:22):
API, or you do control the API,but you can't you know, you're
you're a mobile app developer.You can't deploy them at the
exact same time the way you canwith a front end web app or
anything like that. And now theAPI has to change for one reason
or another. And if you thinkthis doesn't happen in the real
world,
Peter (05:38):
you would
Geoff (05:39):
be wrong because this
happens all the time.
Peter (05:41):
I was gonna say, this
this actually for me may be the
one thing right here because,this happens all the time. And
anyone that has ever said, oh,this will never happen. Life
will be fine. Or if some APIbuilder promises you it won't
change, run. Run for the hills.
Yeah.
Geoff (05:58):
Yeah. And so, yeah, this
has been something that I've
seen at a number of differentjobs where it's like, okay. The
documentation said this valuewill never be null. And all of a
sudden, it's null. And then yourapp is throwing errors,
crashing, silently failing,whatever, depending on what
exactly your language is andexactly, how type strict it is,
that kind of thing.
(06:20):
But yeah. Imagine that the APIhas to change, and now a field
is nullable when it was notpreviously nullable. So now
okay. Fine. You've got to gothrough there, and it's like,
okay.
I marked this field nullable.It's now decoding properly. But
now, everywhere in my view, Ihave to handle this case that it
(06:40):
might be null. And now I'vegotta change every single view
where I've displayed this taskto make sure that this value is
not null, or if it is null, thenI'm doing something with it. You
know, I'm I'm converting it toan empty string.
I'm I'm doing something likethat. And this is the problem,
is that you've now had thingsthat are entirely part of the
(07:02):
API contract now kind of affecthow you build your views. The
solution to this is the termthat I've been using throughout
this episode, and that'sseparation of concerns. Now
separation of concerns, it's anold old old principle. It, was
first coined in 1974 by a veryprolific computer scientist
named Edgar Jijkstra.
(07:24):
I'm sure I mangled that name.It's close enough.
Peter (07:27):
And it's in the show
notes because there's there's no
way I'm gonna try it right now.
Geoff (07:31):
We will Yeah. We will
link to the Wikipedia page for
separation of concerns. It's gothis name on it.
Peter (07:36):
Don't blame us. Yeah.
Geoff (07:39):
Yeah. If you if you've
seen the name, you know who
we're talking about. Anyway, theidea that he kinda put forward
is that each piece of code, andone piece of code is a little
bit nebulous, but we'll justcome come back to that, should
really only have one thing thatit's concerned about. It's the
separation of concerns. And ifyou have multiple concerns, you
(08:01):
should separate them intomultiple pieces of code.
And that can happen at a coupledifferent levels. You can have
that, you know, like, oh, I'vegot multiple types. I got, you
know, different classes. I'vegot different constructs. I've
got different whatever.
Or it can, like, level up, andyou can talk about it at, like,
a process level. That's thewhole UNIX philosophy that
you've got individual smallprograms, and they all do
something well. And so you can,like, pipe them all together on
(08:23):
the command line. But that's thegeneral idea is that something
has one thing that it does, andit does that thing well, and
it's not concerned with otherthings. Some other people may
recognize this as the s inSolid.
That's single responsibility,but, Jekstra got there first. So
yeah. So what we're seeing isour code is not following this
(08:46):
principle. It it is concernedwith two different things. It is
concerned with how it'srepresented on the server.
It's your API contract. And it'sconcerned with how this data is
going to be displayed in yourfront end, in your view. And
that's really already causing usproblems, because if one of
those things changes, now,necessarily, the other thing
(09:07):
also has to change. And so thesolution is, let's separate
those into two different types.And the terms that I'm gonna use
for these types right now,they're not necessarily
universal terms, but, I'm gonnause the terms data models.
You may also hear these calledDTOs or data transfer objects.
It's not necessarily the casethat they have to be objects in
(09:27):
every single language. That'swhy I'm using the term data
models. And domain models. Andthere are a specific subset of
domain models that you'veprobably heard of later.
We'll we'll we'll get into that.But, those are the terms that
I'm gonna use right here. Datamodel, this is what you use to
pass data around. And domainmodels, this is the version of
(09:49):
it that you're using in your appbecause it is specific to your
app's business logic. Anyquestions so far?
Peter (09:56):
No. No. I I mean, I agree
with everything so far that
you've said. Yeah. Hey, folks.
If you like what you're hearingin this podcast and you wanna
help this podcast to continuegoing forward and having great
guests and great conversations,I invite you to become a Patreon
supporter. You can go topatreon.com/compileswift, where
(10:17):
you will get ad free versions ofthe podcast along with other
content.
Geoff (10:22):
Okay. So let's start with
the data model, the the DTO. In
my mind, this should ideallyencode your API contract and no
more, no less. Obviously, that'snot always a % gonna be the
case, but that is the ideal.That really, all you're doing is
you are kinda just saying, thisis what I am speaking to the
(10:45):
API, and, really, I I don't wantto be any more complicated than
that.
There's this idea out there incomputer science, called
Postel's Law. It's also calledthe robustness principle, which
kind of goes by the wording, beconservative in what you send,
be liberal in what you accept.That is, you know, try to take
(11:07):
in whatever you can withoutthrowing an error, without
without really having anyproblems, and try to limit what
it is that you're actuallysending out. Take in everything
that you can without errors,without any other problems, and,
you know, kind of limit what itis that you're sending. You
know, you be consistent even ifwhat you're receiving is not
consistent.
(11:27):
And so to that end, I think thatyou want to have your data
models kind of be as acceptingas possible. In a lot of cases,
I think unless you areabsolutely 100% certain that it
absolutely never ever ever canhave a nullable there, you
should just default to all ofyour fields except null. That
that's that's fine. Just goahead and accept whatever you
(11:50):
can because that way, ifsomething suddenly starts
becoming null, you're not, youknow, suddenly failing decoding
because you didn't expect that.
Peter (11:58):
Okay. I do wanna jump in
there. Just to clarify, though,
just just wanna make sure I'munderstanding what you're saying
because, I'm always drumminginto folks, you know, allow for
the outcome to be somethingother than you expect. Right? Of
which a null is a perfectexample of that.
Right? What just just becausesomeone tells you, look, this
(12:20):
piece of data will always bethere for you. You. That is the
first sign to say I'm gonna codefor when it's not there. Because
they more than they the morethey promise it'll be there, the
more I tell myself it won't beone day.
Right? Yep. So, you know, makesure you cover your bot on that.
Right?
Geoff (12:39):
The other thing I think
that you should do in accepting,
things as they are from the APIcontract is don't have any sort
of type that you're decoding tothat is not something that your
transfer protocol can represent.So let's use the example of
JSON. Everybody knows JSON.Everybody knows what's in JSON.
You've got objects.
(12:59):
You've got arrays. You gotnumbers. You got strings. You
got whatever. What you don'thave in JSON is dates.
That's not a thing. You canrepresent that as, say, a number
that's your unit set box. Youcan, have a string that's like
an ISO eighty six zero onestring, that kind of thing.
(13:20):
Don't try to encode in your APIcontract the idea of a date.
Just take in a string if that'swhat your system is gonna send
you.
If it's gonna send you a string,keep it as a string. I know that
some languages again, we'regonna go back to Swift. That's
kind of our bread and butter,have things like, oh, well, you
know, you can put a date in youra p in your codable struct, and
(13:43):
you can have some setup therethat that go ahead and decodes
it for you on on the fly. Don'tuse those. You should take in a
string.
If it's a string, we'll figureout whether or not it can be
converted to a date later.Accept what your API can give
you. Don't accept anything else.
Peter (14:03):
I do I very much agree
with that because, you know,
okay. I get it. Folks havevarying opinions on this for
sure. Right? But I always, youknow again, I think to myself,
look.
If something's coming in, thethe most the if something's
coming in, the easiest thing toalways handle is gonna be a
string. Right? Get your string,convert it or or check that you
(14:26):
can convert it to what you need,but just by sending string back
and forth simplifies the wholething. Right? The amount of
times that I've spoke, you know,had conversations with API
engineers and it's like, look, Iwant a date and it's like, well,
we're gonna send you a string.
But that means I gotta convertit. Well, that's a good thing.
It means I can test that and andensure that this string will
(14:50):
convert to some kind of sensibledate. Right? Yep.
Geoff (14:56):
We have a person in the
chat right there, saying one
other one that I I forgot. In alot of cases, your API contract
will specify a kind of pseudoenumeration type, where it's
just like, oh, it can be one ofthese three values. And in a lot
of languages, you have this ideaof, like, on the fly decoding,
you're gonna say, this is theenum value that it can be, but
(15:20):
what that actually is in theJSON is just a string. Again,
take that as a string now.You're gonna run into a point
where, oh, the you had handledthe three enum types that you
had, and now the API is sendinga fourth enum type.
And now your decoding is broken.Don't do it. Take it in as a
string. You can always convertit later. We're we're gonna
(15:41):
we're gonna get to that pointlater in the in the podcast.
Your data contract, your datatype there, it should handle a
string.
Peter (15:49):
Done. Agreed. Yep. And
and let me say because I know
folks out there who know me,they're gonna say, but, Peter,
you're always saying how muchyou hate, you know, string using
strings for things like stringmatching and and so on and so
on. Yes.
That is true. But this is thisis a different thing we're
talking about here. Right? Thisthis data coming in needs to be
(16:09):
as simple as it can be, and Idon't think you get simpler than
a string.
Geoff (16:13):
Yeah. And we we we have
other options coming up. So
let's talk about those now. Theother side of this is your
domain models. In your domainmodels, you can do all of these
things.
This is what you want here. Thisis a representation suitable for
your app. This is this is whatyou're gonna use in your app.
This is how you're gonna passdata around throughout your app.
(16:34):
So you can have the things thatyou want.
You can have non optionalvalues. So you know that, like,
if I've if I'm dealing with thisat all, it's not optional. It
it's going to be there. We'vewe've guaranteed in the type
system that it is there. You canhave these more complicated
representations, such as dates.
You can say, like, okay. This isa real date. This has a time
zone associated with it. We cando date math on it. We can do
(16:56):
whatever we want.
It it's it's handled there. Youcan have your enums so that
you're not doing the thestringly typed, stuff that Peter
was just railing about, whereyou're you're comparing strings
or you're comparing any of theother things. You can have all
of these nice things inside ofyour app, and they're not
connecting to the the API.They're not part of your API
(17:20):
contract. Now the version ofdomain models that I think a lot
of people are going to befamiliar with and may not have
recognized this quite yet, but,will click as soon as I say it.
One of the most common types ofdomain models are view models.
So this is a case where you'vegot a version of data as it
(17:43):
needs to be represented in theapp, and it is explicitly set up
in a way that it is meant to bedisplayed at at this point. That
that is your model as it is donefor a view view
Peter (17:56):
model.
Geoff (17:57):
Fairly straightforward
name there.
Peter (17:58):
Yep.
Geoff (18:01):
And I think in a lot of
simple apps, this may be all you
need. You need your data model,and you need your view model.
And those two things are yourconnections. I think the reason
that I use the term domain modelhere is that I think it's a
little bit limiting for morecomplicated apps to say that
those are your only two models,and that in a lot of cases, it
almost makes sense to have anextra layer there where you have
(18:22):
your data model, you have yourinternal business logic domain
model, and you have your viewmodel, and you kind of map
between all well, you kind of gothrough the center of domain
model. And so you can go fromdata model to domain model.
You can go from domain model toview model. You can go from view
(18:43):
model to domain model. You cango from data to domain, but you
don't you don't ever go fromview to data. You you always go
through that central domainmodel.
Peter (18:52):
I do wanna jump in and
and point that out because, it
kills me that I still comeacross folks who will take that
incoming data, push it straightinto a view, do whatever, and
send it straight back outthrough the data again. And it
drives me crazy. Not the goodway to go, folks. Right? Just
like we were saying those APIschange.
(19:13):
Well, if that data changes, yougot a whole bunch of rework, and
I just think it's a it's a badpractice to not have that
middleware layer with the viewmodels. That's that's just my
2¢.
Geoff (19:26):
So let's talk about the
implementation. How would you
actually go about doing that?How how do you actually go
about, you know, maintainingthese two separate models? So I
think the core of what you havein your app is you have one type
that is responsible for actuallydoing the communication with
(19:46):
your API. And one thing to lookup that may not be the solution
for everybody, but is definitelya good starting point, is the
idea of the repository pattern.
And that is basically a way ofsaying, like, I have one thing
that handles communicating withmy data, and what I send to and
(20:10):
receive from that is just mydomain model. The repository,
internal to itself, handles thedata model, and it references
the data model because it needsto con talk no. Sorry. Because
it needs to talk to the API. Butoutside of the repository, you
should never see that datamodel.
You're only dealing with thedomain model at that point. And
(20:33):
the way that you handle that isthrough the use of data mappers.
What those are are specifictypes for saying and data
mappers are for convertingbetween your data type and your
domain type and vice versa. And,really, what they're there for
is for handling all of thecomplexity there. And stuff
like, okay.
(20:54):
We have this date as a string.We need it as an actual date.
Oh, we can't parse it. Now we'reable to say, here is the
specific error. Here is thespecific object.
Here is the specific cause ofthis failing. And so all of the
complexity of error reporting isthere in your data mapper. And
your data mapper can really,like, do all of whatever
(21:15):
complicated finagling it needsto do. Your data mapper can
handle, oh, we've got, like,multiple different versions of
the API. If we see version oneof this thing, well, it's, you
know, ISO eighty six zero onestring.
If we see version two of this,it's, oh, it's got, you know, a
time zone associated with itwhere it didn't before, that
kind of thing. All of thatcomplexity goes into your data
(21:38):
mapper type. That way, you don'thave to have it in your domain
model or in your data model. Youdon't have to have it in your
repository. Everything's justkind of centralized.
This is what converts from thisthing to the other thing. Time
for a break.
Peter (21:52):
Hey, everybody. It's
Peter Whittam here from the
Compulsory podcast. I'm gonnatell you about Setapp. Setapp is
a service that provides asubscription fee of just $10 a
month, and you get access toover 200 Mac applications and
it's also available now on iOSas part of that deal. I use the
(22:12):
service because it just has aton of really good first rate
apps that I use all the time.
And for me, it's invaluable as adeveloper to have access to
tools for things like APIs, forplanning projects, writing
emails, writing documentation.And you get all of these things
including database apps, all ofthat kind of stuff right there
(22:34):
on the setup service for just$10 a month. You can use as many
or as few applications as youneed. If you're interested in
checking this out, go topeterwidham.com, p e t e r w I t
h a m Com forward / set app, s et a p p. And you can see the
details there, and it's got alink that you can go over and
(22:56):
start using the service and seehow it works out for you.
I strongly recommend this toevery Mac user.
Geoff (23:03):
Break time over.
Peter (23:07):
Okay. Great. Now
everything you have said so far,
this may be a unique episodebecause I completely agree with
you. So write that on thecalendar, folks. Alright?
It's not gonna happen veryoften. But one of the things
that I think is a good examplehere is testing your code. And
like you said, like finding bugsand also when the when the APIs
(23:28):
change, when your business logicchanges, all of these things,
the separation of concerns are agreat way to say, great. I'm
only rewriting this small chunkof my code. I'm not rewriting
some massive refactoring of myapp.
Right? But I I think that it oneof the important ones is it does
make it, in my opinion, verytestable as and hey. That that
(23:50):
should be a huge benefit rightthere. So, you know, let's talk
about some of the benefits ofdoing this offset again because
I'm sure there are folks thatare like, oh, but this is so
much work. So let's talk aboutthe benefits of why this is
important.
Geoff (24:04):
With each of these pieces
kind of handling just a small
section of it, it makes it mucheasier to test because you don't
have to build up this kinda,like, full pipeline. So for
example, I just discussed thesedata mappers. Having something
where you were previouslysaying, okay. You know, if if
I've got this version of this, Ineed this. If I've got this
version of it, I need this.
That's gonna be reallycomplicated if what you're
(24:25):
dealing with is, like, your endof view. You're gonna have to
pass a bunch of stuff to it andand make sure that you've got,
like, just data. And I've seenso many things where people are
just like, oh, we're mocking outour entire networking stack
because, you know, we're we'regetting rid of, of everything
because, you know, at the endview, like, we need to be able
(24:47):
to say what the JSON was. Andit's like, this is this is too
much. Like or what's worse ispeople are just saying, that's
too much work.
We're just not gonna do it.Whereas with this, where it's
like, okay. You've got one smallpart of this, and you can say, I
am passing this very specificdata into here, and I expect
this very specific data backout. It makes it very easy to
(25:09):
test. It also means that youhave, like we said earlier, the
ability to handle changeswithout having to really have
that cascade between the rest ofyour app.
So that's the small changes thatwe discussed, like, you know,
nullable fields, or non nullablefields being suddenly becoming
nullable, things like that. But,also, like, I've seen just
(25:34):
gigantic migrations that wentawry because of a lack of
separation of concerns. Youknow? At a past job, we had a a
case where, the entire app wasbuilt on gRPC and protocol
buffers. I'm not gonna explainwhat those are.
But just generally, like, that'sthe the way that we communicated
(25:54):
with our API. And then it wentto GraphQL, and and we were
suddenly speaking GraphQL. Nowthe problem was all of our gRPC
objects, were being useddirectly in the UI. So what does
that mean when we switch toGraphQL? Well, that means not
only do we have to change ournetworking layer, we have to
change every single piece of ourcode
Peter (26:16):
Yep.
Geoff (26:16):
To make sure that it's
it's now handling this new
GraphQL. And if I recallcorrectly, like, it didn't even,
like, all move over at once. Soit was just like, oh, we've got,
like, protocol buffers overhere, and we've got GraphQL over
here. And they don't reallycommunicate with each other, and
it was just a nightmare. And andthis is a case where having that
(26:39):
all kinda separated away in thethe first place would have saved
us a ton of headaches.
Peter (26:45):
Yeah.
Geoff (26:46):
If this was something
where it's like, once you hit
that repository layer, you don'thave to worry about whether it's
protocol buffers or GraphQLanymore, that would have been
great, especially in a, like, alarger company where you may
have separate teams. You've got,like, a platform team. You've
got feature teams dedicated tospecific parts of the app. Why
do your feature teams need tocare about what's going on with
(27:08):
the network? Like, thatshouldn't matter.
They should be able to buildthat kind of stuff without it.
And then to that to that sameextent of, like, the separation
of teams, like, if you arebuilding something like this and
you know that you're able torely on some kind of internal
business tool, what that meansas well is that you as the front
end team, you as the mobile appteam, you as the whatever team,
(27:31):
you can go ahead and startbuilding your features to these
internal types without the backend being available yet. That
was another thing that I've seena lot in a lot of different
companies is people going, well,we need to build this feature,
but we can't build this featureyet because the back end team,
they haven't finished the backend yet. And, you know, it's
great to use that as an excusewhen you don't wanna actually do
(27:53):
anything. But you can actuallybuild these things.
You like there's no reason whyyou necessarily need to wait on
the back end team for somethinglike that until what you're
building is that data mapper,that repository side. You can
build out your entire featureagainst these internal domain
models, and then all you needthe back end for is that
conversion between the two. Andyou can go ahead and be on your
(28:17):
merry way without having to beblocked by this other team.
Peter (28:21):
I I would like to say,
and and I get it. Maybe it's
controversial. I think that ifyou find that you are saying, I
can't do, you know, let's justtake a date. Right? Okay.
I can't do this build this partof the app yet because I don't
have this the the data this datethat I need to put on here and
(28:42):
see how it's gonna look. Thatshould be your number one sign.
You have not thought thisthrough or you're doing it wrong
because
Geoff (28:53):
What's the process
equivalent of the code smell?
Peter (28:55):
Exactly. Right. You know,
because I agree with you
completely. Yes. Okay.
There is a benefit to havingeverything you need at a certain
point as early as possible sothat you can code and test and
and everything else. But if youare in some way saying you are
dependent upon that to build outpart x of the app, I would go so
(29:19):
far as to say, well, then you'reprobably the problem, not where
the past experience at
Geoff (29:25):
a company where the back
end that we were waiting for was
a piece of hardware. Like, wewere communicating with a
Peter (29:34):
piece of hardware that
had to be manufactured and
prototyped and all of that.
Geoff (29:35):
And it's, like, a piece
of hardware that had to be
manufactured and prototyped andall of that. And it's like, if
we had sat there the entire timeand said, well, we actually
can't build any of the app yetbecause we need this hardware to
happen, like, we wouldn't havehad a job for six months. Yeah.
And so, yeah, you you need theability to kind of have internal
things that you can deal withand then be able to just mock
(29:59):
out just that last little bit.They're like, I know that I need
this feature.
I'm gonna need this data. Andthen, like, you can build your
domain model that has the datathat you need and work with
that. And then it's like, okay.At some point, probably before
the back end is actually, like,up and running, then you get the
(30:20):
spec doc, and then you can kindastart building the mappers
together. The you know, youyou'll have your mapper like,
you can build the mapper, andyou can go like, okay.
This is what we know the APIcontract is gonna be. This is
gonna deal with that. And then,like, that last little bit is
just, like, the URL sessionconnection. Like, just hook it
up to, the actual network. But,yeah, like, because you can you
(30:44):
can have different levels ofthat.
You can have, your repositoryjust then, the the the final
result to you. That's normallywhat I do when I need to mock
out the repository is I justsay, like, okay. It just does
this. But you can also mock out,like, the network layer above
the repository and say, like,okay. This network layer is
(31:04):
vending me the data models, andthen that's going through my
repository, and that's goingthrough the mappers, and then
it's going through the, domainmodel.
But, honestly, most of the time,I just I just mock out the
repository and say, yeah. Justgo ahead and return these domain
models. And I I kinda skippedthat other little bit. So, yeah,
(31:26):
I think that's basically all Ihave to say about this for now.
You know, the there's a lot ofbenefits you get from this.
It does take some extra workupfront, but I think it allows
you to be much more explicitexplicit about everything that
you're trying to do, and itobviously has a lot of these
these upfront benefits. So, Idefinitely recommend, definitely
(31:47):
look at the links that we'veincluded, do some more, in-depth
reading about this. But reallystart to think about this the
next time that you're buildingout any of these kinds of things
in your app. And it really makesit so that it's it's easier to
continue to expand, to continueto test, to, you know, react to
changes, unexpected changes inin your your back end. You get a
(32:12):
lot of nice wins from this.
And so, I I I definitelyrecommend, you know, taking a
look, see where you can improveyour apps that way.
Peter (32:19):
Yeah. And I think it's I
wanna point out here, I
personally believe it is betterto spend this time thinking
about these things upfront andavoid incurring that technical
debt later on when you have todeal with these problems because
you didn't go through thisprocess. And I think that when
(32:40):
you are designing your app andby designing I don't mean the UI
and everything. I mean whenyou're architecting it and then
have these at the forefront ofyour mind. Right?
This is what this looks likenow. What if this changes next
week? Because as we saidearlier, next week, if you if
you've ever worked with teams ina company and big products or
(33:01):
things like that, next weekalways happens when they change
it or six months from now whenthey pivot to some new thing or
you get bought out and itbecomes something else. So plan
for it now. Right?
Stop the technical debt beforeit happens. It's not gonna
completely solve all yourproblems, but it'll
compartmentalize some of yourproblems with smaller
(33:24):
refactoring. That's
Geoff (33:26):
that's a that's a great
way of putting it. It it
compartmentalizes your problems.The when you have problems and
you will have problems, that'sthe nature of software
development, you limit the areaof impact that you have. You
know? If something changes, youreally have, like, this firewall
of the repository and saying,it's not gonna spread beyond
(33:48):
this because everything else,like, it's cut off from that.
That is that is your breakpoint, and and you're not really
gonna have to, rearchitect yourentire app because one other
thing changed.
Peter (34:02):
Yeah. Agreed. And also as
as we know, you know,
developers, hey, they they hatehaving to go back and redo
things. They like to do newthings and cool things. Well, if
you do this, guess what?
You're gonna be going back lessand and spending time on this.
Alright, Geoff. Well, thank youso much for this. Folks, we will
put links in the show notes tothe article. Go read it and keep
(34:24):
it at the forefront of yourmind.
Geoff, where can they find you?
Geoff (34:27):
You can find everything I
do at cocoatype.com, even though
that's not actually where theblog post is this week. There's
a link to it from cocotype.com.
Peter (34:35):
So Yeah. Cocoatype.com is
is the Geoff starting point.
Right? And for me, the startingpoint is peterwitham.com. Folks,
if you like what you're hearinghere, right, come and join us on
our dev club Discord.
Again, there'll be links in theshow notes for this. This is the
kind of stuff, we talk aboutthis a lot. We talk about many
different topics related todevelopment, but these are the
(34:58):
key areas, that come up a lotand, you know, we get asked a
lot of these questions. Andgoing in our Discord where these
conversations are taking place,not only do you get to be part
of it, but there's all thesefantastic references. You can
cause it.
Yeah. You can cause theseproblems. Yeah. Cool cool cool
sort of the infighting aboutcompartmentalization. Alright?
(35:19):
But that's it, folks. That'swhat we got for you. I hope this
has been helpful. Let us know.Leave us a review.
If you wanna go the extra step,hey, there's the link for the
Patreon. We greatly appreciatethat. Thank you, folks. We will
see you in the next episode.