Re: [testdrivendevelopment] "Find or Create" functions: a discussion
"Ahmet Murati" <[email protected]> Sun, 24 Nov 2019 08:59:30 +0000
| Newsgroups | gmane.comp.programming.test-driven-development |
|---|---|
| Message-ID | <CH2PR14MB37075A1292F5D26BE9113166EE4B0@CH2PR14MB3707.namprd14.prod.outlook.com> |
--_000_CH2PR14MB37075A1292F5D26BE9113166EE4B0CH2PR14MB3707namp_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable When developing web applications we should bear in mind that some people th= at do not want to have I.e. any citizenship, this would lead to dirty data Mit Freundlichem Gr=FC=DFen Ahmet Murati Software developer & Translator E-mail: [email protected] E-mail: [email protected] Handy: +4915123015776 ________________________________ From: [email protected] <[email protected]> on= behalf of J. B. Rainsberger <[email protected]> Sent: Sunday, November 24, 2019 9:55:36 AM To: [email protected] <[email protected]> Subject: [testdrivendevelopment] "Find or Create" functions: a discussion Hi, folks. An old issue came back to the surface this month in consultatio= n with clients and I'd like your opinion. It regards the old "find or creat= e" pattern. It seems to violate Command/Query Separation (as I understand i= t), but it seems handy and harmless, so I'd like to find out more about wha= t you folks think about it. Benign? Problematic? I imagine using this with the Repository pattern. Let's say we register a = patient in a medical environment and so we need a UI that reduces as much a= s possible the number of steps. We don't want to force the user to look up = a patient just to discover that the hospital has no record of them, so we a= llow the user to enter some basic identifying information. This information= suffices to either find an existing patient or create a new one if our dat= abase doesn't know that patient. The result is something like Patient registeredPatient =3D patientRepository.findOrCreate(patientIdenti= fyingInformation); The identifying information might have basics like name, date of birth, it= doesn't matter. We can guarantee that registeredPatient now represents an = Entity in our system, either because we found someone that matched the iden= tifying information or because we created one. This appears to violate CQS, but it seems like a good thing to have. Some = individuals struggle with this, because they don't know whether this is an = area where CQS "doesn't matter" or an area where CQS is trying to teach the= m something and they can't see what they're meant to learn. I haven't thoug= ht about this in depth in years, so I feel the same way right now. Drawback= s? Alternatives? I was also thinking about how to design this, and it seems to me like a sp= ecial case of getOrAbsent(), so that I could implement the generic findOrCr= eate() algorithm with something like repository.find(identifyingInformation).orElse(T::createFromIdentifyingInf= ormation) where find() returns Maybe TIdentifyingInformation and T has a named const= ructor for creating a T from a TIdentifyingInformation. I'm assuming here t= hat TIdentifyingInformation is enough to provide all the mandatory properti= es of T. With this design, I don't need a single findOrCreate() function any more, = because the pieces find() and orElse(T::create) communicate the idea well e= nough. Thoughts? I'm happy to see the discussion meander. Is this a totally-solve= d issue and there's one clear good way to proceed? or is it more a matter o= f context or preference? -- J. B. (Joe) Rainsberger :: https://tdd.training<https://eur02.safelinks.pr= otection.outlook.com/?url=3Dhttps%3A%2F%2Ftdd.training&data=3D02%7C01%7C%7C= 3d347c93073d490e49b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0= %7C637101825578440108&sdata=3DPrF8bFTpB%2FldS1BqWrhY8yjvnzIRCBye0HR8hMy2W5Q= %3D&reserved=3D0> :: http://www.jbrains.ca<https://eur02.safelinks.protecti= on.outlook.com/?url=3Dhttp%3A%2F%2Fwww.jbrains.ca&data=3D02%7C01%7C%7C3d347= c93073d490e49b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C63= 7101825578450119&sdata=3DPoxbqrXKmUWEmr%2FB2anjLMzBDzN3JQ5nW9ZG1OficJs%3D&r= eserved=3D0> :: http://www.thecodewhisperer.com<https://eur02.safelinks.pro= tection.outlook.com/?url=3Dhttp%3A%2F%2Fwww.thecodewhisperer.com&data=3D02%= 7C01%7C%7C3d347c93073d490e49b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaa= aa%7C1%7C0%7C637101825578460124&sdata=3DKuaRplAiCAXg12r1CbPxdOudcmQTmte2mq4= 069dG%2B5M%3D&reserved=3D0> -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#35754): https://groups.io/g/testdrivendevelopment/mess= age/35754 Mute This Topic: https://groups.io/mt/61872506/3268755 Group Owner: [email protected] Unsubscribe: https://groups.io/g/testdrivendevelopment/leave/6156322/74455= 6386/xyzzy [[email protected]] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --_000_CH2PR14MB37075A1292F5D26BE9113166EE4B0CH2PR14MB3707namp_ Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable <html> <head> <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859= -1"> </head> <body> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> When developing web applications we should bear in mind that some people t= hat do not want to have I.e. any citizenship, this would lead to dirty data <br> <br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> <span id=3D"OutlookSignature"> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> <br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> Mit Freundlichem Gr=FC=DFen <br> <br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> Ahmet Murati<br> <br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> Software developer & Translator<br> <br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> E-mail: [email protected]<br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> E-mail: [email protected]<br> </div> <div dir=3D"auto" style=3D"direction: ltr; margin: 0; padding: 0; font-fam= ily: sans-serif; font-size: 11pt; color: black; "> Handy: +4915123015776<br> </div> </span><br> </div> <hr style=3D"display:inline-block;width:98%" tabindex=3D"-1"> <div id=3D"divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, sans-serif" s= tyle=3D"font-size:11pt" color=3D"#000000"><b>From:</b> testdrivendevelopmen= [email protected] <[email protected]> on behalf of J. B. Rain= sberger <[email protected]><br> <b>Sent:</b> Sunday, November 24, 2019 9:55:36 AM<br> <b>To:</b> [email protected] <testdrivendevelopment@group= s.io><br> <b>Subject:</b> [testdrivendevelopment] "Find or Create" functio= ns: a discussion</font> <div> </div> </div> <div> <div dir=3D"ltr"> <div>Hi, folks. An old issue came back to the surface this month in consul= tation with clients and I'd like your opinion. It regards the old "fin= d or create" pattern. It seems to violate Command/Query Separation (as= I understand it), but it seems handy and harmless, so I'd like to find out more about what you folks think about it. Benign?= Problematic?</div> <div><br> </div> <div>I imagine using this with the Repository pattern. Let's say we regist= er a patient in a medical environment and so we need a UI that reduces as m= uch as possible the number of steps. We don't want to force the user to loo= k up a patient just to discover that the hospital has no record of them, so we allow the user to enter some ba= sic identifying information. This information suffices to either find an ex= isting patient or create a new one if our database doesn't know that patien= t. The result is something like</div> <div><br> </div> <div>Patient registeredPatient =3D patientRepository.findOrCreate(patientI= dentifyingInformation);</div> <div><br> </div> <div>The identifying information might have basics like name, date of birt= h, it doesn't matter. We can guarantee that registeredPatient now represent= s an Entity in our system, either because we found someone that matched the= identifying information or because we created one.</div> <div><br> </div> <div>This appears to violate CQS, but it seems like a good thing to have. = Some individuals struggle with this, because they don't know whether this i= s an area where CQS "doesn't matter" or an area where CQS is tryi= ng to teach them something and they can't see what they're meant to learn. I haven't thought about this in depth in yea= rs, so I feel the same way right now. Drawbacks? Alternatives?</div> <div><br> </div> <div>I was also thinking about how to design this, and it seems to me like= a special case of getOrAbsent(), so that I could implement the generic fin= dOrCreate() algorithm with something like</div> <div><br> </div> <div>repository.find(identifyingInformation).orElse(T::createFromIdentifyi= ngInformation)</div> <div><br> </div> <div>where find() returns Maybe TIdentifyingInformation and T has a named = constructor for creating a T from a TIdentifyingInformation. I'm assuming h= ere that TIdentifyingInformation is enough to provide all the mandatory pro= perties of T.</div> <div><br> </div> <div>With this design, I don't need a single findOrCreate() function any m= ore, because the pieces find() and orElse(T::create) communicate the idea w= ell enough.</div> <div><br> </div> <div>Thoughts? I'm happy to see the discussion meander. Is this a totally-= solved issue and there's one clear good way to proceed? or is it more a mat= ter of context or preference?<br> -- <br> <div dir=3D"ltr" class=3D"x_gmail_signature"> <div dir=3D"ltr"> <div>J. B. (Joe) Rainsberger :: <a href=3D"https://eur02.safelinks.protect= ion.outlook.com/?url=3Dhttps%3A%2F%2Ftdd.training&data=3D02%7C01%7C%7C3= d347c93073d490e49b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%= 7C637101825578440108&sdata=3DPrF8bFTpB%2FldS1BqWrhY8yjvnzIRCBye0HR8hMy2= W5Q%3D&reserved=3D0" originalsrc=3D"https://tdd.training" shash=3D"LWf7= sNi6sBxcNTPMo7s7kxAlm5XDsGBesok/cHPJiHqL8xadnRLULubdw/NLvcuHi9ik9Xeg18C/HRO= UQRvALS9XdBaDJn9okutPTFqsJ8+y2sIsWymEW+JnD5FgxcRUrnPc7G6WskBoW2Bnug= hdmAk+1SXMg5dHlUdDH1giQmw=3D" target=3D"_blank"> https://tdd.training</a> :: <span><a href=3D"https://eur02.safelinks.prote= ction.outlook.com/?url=3Dhttp%3A%2F%2Fwww.jbrains.ca&data=3D02%7C01%7C%= 7C3d347c93073d490e49b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7= C0%7C637101825578450119&sdata=3DPoxbqrXKmUWEmr%2FB2anjLMzBDzN3JQ5nW9ZG1= OficJs%3D&reserved=3D0" originalsrc=3D"http://www.jbrains.ca" shash=3D"= IBFIHF6wuG/u9vyUbyHDYrtucf/J2tNwdmUBAhAKnurIgZRuBYjyhXYILjofLgfQ9bcP7jDlKVp= tsq8DXx7SjKeXCkaNZ4E4/yVCdeSEJNHETKzcDEyBZlIEyoGZORpG0Wc/OR/t/ntOz7cqmigD4V= JT/at0cvj84XAkjtU/acE=3D" target=3D"_blank">http://www.jbrains.ca</a> :: <a href=3D"https://eur02.safelinks.protection.outlook.com/?url=3Dhttp%= 3A%2F%2Fwww.thecodewhisperer.com&data=3D02%7C01%7C%7C3d347c93073d490e49= b908d770bc1ebc%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637101825578460= 124&sdata=3DKuaRplAiCAXg12r1CbPxdOudcmQTmte2mq4069dG%2B5M%3D&reserv= ed=3D0" originalsrc=3D"http://www.thecodewhisperer.com" shash=3D"li3a5Oe8v5= OjKYhrlLidpcD4zo88xNm/qYSMVtWZqs4/HoSNRY7yMUqno2/q5soZ7dDpSmj4NZiYfCP+1= tXWeo7zLLJ+gDX7sdxafaqUIz37UIQ96e41i14M9z4xPmnWp+lKll6GpuxphcmcIeyN= ZMKSs1b4kgM9n+dk5ep5Aww=3D" target=3D"_blank"> http://www.thecodewhisperer.com</a></span></div> <div><br> </div> </div> </div> </div> </div> </div> </body> </html> <div width=3D"1" style=3D"color:white;clear:both">_._,_._,_</div> <hr> Groups.io Links:<p> You receive all messages sent to this group. <p> <a target=3D"_blank" href=3D"https://groups.io/g/testdrivendevelopment/mes= sage/35754">View/Reply Online (#35754)</a> | <a target=3D"_blank" href=3D"mailto:[email protected]?subj= ect=3DRe:%20Re%3A%20%5Btestdrivendevelopment%5D%20%22Find%20or%20Create%22%= 20functions%3A%20a%20discussion">Reply To Group</a> | <a target=3D"_blank" href=3D"mailto:[email protected]?subject=3D= Private:%20Re:%20Re%3A%20%5Btestdrivendevelopment%5D%20%22Find%20or%20Creat= e%22%20functions%3A%20a%20discussion">Reply To Sender</a> | <a target=3D"_blank" href=3D"https://groups.io/mt/61872506/3268755">Mu= te This Topic</a> | <a href=3D"https://groups.io/g/testdrivendevelopment/post">New Topic</a>= <br> <br> <a href=3D"https://groups.io/g/testdrivendevelopment/editsub/3268755">Your= Subscription</a> | <a href=3D"mailto:[email protected]">Contact Group Own= er</a> | <a href=3D"https://groups.io/g/testdrivendevelopment/leave/6156322/7445563= 86/xyzzy">Unsubscribe</a> [[email protected]]<br> <div width=3D"1" style=3D"color:white;clear:both">_._,_._,_</div> --_000_CH2PR14MB37075A1292F5D26BE9113166EE4B0CH2PR14MB3707namp_--