tag:blogger.com,1999:blog-13967713.post8768723015772698276..comments2016-05-11T20:05:39.322+02:00Comments on Carlo Pescio: Life without Stupid Objects, Episode 1Carlo Pesciohttp://www.blogger.com/profile/12652284939993729858noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-13967713.post-68727287063432291832013-03-05T14:55:26.497+01:002013-03-05T14:55:26.497+01:00I agree that Annotations in code constitute a coup...I agree that Annotations in code constitute a coupling, since they import the mapping layers code. So mapping with XML files is preferred here.<br /><br />Could you maybe elaborate shortly on how they constraint architecture choices? Are you writing your persistence code manually then and implement "custom ORMs" for every use-case?Anonymoushttps://www.blogger.com/profile/03607161164414378678noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-6168619196586618852013-02-25T14:46:30.140+01:002013-02-25T14:46:30.140+01:00Benjamin: sure, a purely reflection-based persiste...Benjamin: sure, a purely reflection-based persistence layer (based on attributes/annotations in code or on external mapping artifacts) does not constitute a coupling between persistence and domain. <br /><br />Strictly speaking, if you do it with attributes or annotations in domain classes, it qualifies as the opposite (we put some persistence concerns into the domain). <br />It can be harmless, and I've done it quite a few times, but those annotations often reveal (for instance) a bias toward relational mapping, percolated into the domain layer.<br /><br />Overall, I'm not using Hibernate-like frameworks much. They come with a lot of assumptions and consequences, and they're rarely a good fit for the kind of projects I'm involved with. They also tend to constrain my architectural choices, which I don't like much. Your mileage may vary :-)<br />Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-59325969407026214392013-02-23T10:06:27.153+01:002013-02-23T10:06:27.153+01:00What is your opinion about Reflection based persis...What is your opinion about Reflection based persistence infrastructure? Generally you could create a repository that accepts "object", in languages that have them use generics to specify this to and then have the persistence layer analyze this data based on reflection + metadata mapping.<br /><br />My question hints at, if you would consider Hibernate/JPA type persistence sufficient to avoid a dependency from persistence to the domain layer (that we wan't to avoid).Anonymoushttps://www.blogger.com/profile/03607161164414378678noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-73387605988864698012012-09-30T09:31:35.465+02:002012-09-30T09:31:35.465+02:00Daniele: yes, but that technique does not scale ve...Daniele: yes, but that technique does not scale very well, for instance, when you consider this simple variation:<br /><br />class UserRepository<br />{<br />public List GetUsers( some condition here )<br />{<br />//...<br />}<br />}<br /><br />because you return an unbound number of objects. You can pass a prototype object to clone, but it's less than ideal.<br /><br />If you see the different solutions as points in a decision space, then:<br /><br />- passing a mutable objects works well for single-object scenarios<br /><br />- generic programming works well [also] for multiple-object scenarios, yet tend do break for deeply nested objects<br /><br />- IoC works well [also] for deeply nested objects<br /><br />- none is really perfect when you want to choose the actual implementation among sister classes, based on some condition. Some IoC are more helpful than others here, or a Product Trader is needed (most people use the term Factory when they're in fact implementing a product trader).<br />Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-6588852343642120982012-09-29T22:11:50.250+02:002012-09-29T22:11:50.250+02:00Carlo,
maybe I miss something (I don't have m...Carlo,<br /><br />maybe I miss something (I don't have much experience with this kind of application) but instead of using templates, can't I simply use polymorphism like this?<br /><br />class UserRepository<br />{<br /> public void FillUser( int key, UserData user )<br /> {<br /> // fill user with data (needs "set" methods in UserData)<br /> }<br />}<br /><br />class MyWonderfulUseCase<br />{<br /> public void DoSomethingUseful()<br /> {<br /> // ...<br /> User u = new User();<br /> userRepository.FillUser( key, u );<br /> bool b = u.isBirthday(); // u is a full-fledged domain object :-)<br /> // ...<br /> }<br />}<br /><br />thanks a lot<br />Daniele<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-13967713.post-19302725148269456272012-08-09T13:47:16.512+02:002012-08-09T13:47:16.512+02:00Stomi: a partial answer to your question will be a...Stomi: a partial answer to your question will be at the core of the next episode.<br /><br />Generally speaking, OO is relatively ok with collaborators. Is not so ok on having stupid parties involved in a collaboration :-). <br /><br />In many cases (I had this conversation just today) the problem seems to be that some classes (like user) tend to be seen at the center of many tasks, where in fact the only thing we need to know is the user identity. Allocating all those behaviors to the user is a perfect way to end up with a bloated class. Exposing identity, on the other hand, is not a huge breach of encapsulation.<br /><br />More on this stuff next time :-)Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-40293632773096505502012-08-08T22:43:51.335+02:002012-08-08T22:43:51.335+02:00Hello,
What if a domain object (User) needs some ...Hello,<br /><br />What if a domain object (User) needs some external collaborator passed as a constructor argument for example? I'm not sure how much responsibility of a domain object should have, but it may happen that it requires other collaborators.<br /><br />I would be interested in hearing your opinion about hybrid objects, which have both lots of accessors and behavior. The user looks like one of them to me, and it just feels wrong for me. It can happen that we need to change the behavior in some scenarios but without changing the data. But separating this behavior to other objects requires less encapsulation.stominoreply@blogger.comtag:blogger.com,1999:blog-13967713.post-80892905708608904332012-07-20T15:12:35.109+02:002012-07-20T15:12:35.109+02:00Fulvio:
But my intuition is that layers should is...Fulvio:<br /><br /><i>But my intuition is that layers should isolate services which present themselves as cohesive entities. Such as virtual memory, as in your example. A "Business" layer doesn't seem so cohesive as virtual memory, does it?</i><br />---<br />Right, it does not. Which seems to suggest that layering is not a natural shape here....<br /><br /><br /><i>but I can't remember of a way for visually representing this kind of relationships between artifacts and runtime objects. Have you found a good one?</i><br />--<br />Not really, but I haven't been looking either :-)<br /><br /><br /><i>Do you manage to spot entanglement before you code? Which "tools" are you using?</i><br />--<br />sure (actually code is sometimes hiding things in a sea of details). I honestly don't know how - I just see it. I wish I could be more helpful - maybe one day I'll figure that out, but at this stage, you guys have to learn to see on your own :-)Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-66592513550002010712012-07-19T19:03:42.630+02:002012-07-19T19:03:42.630+02:00It's just a consideration, not a real comment!...It's just a consideration, not a real comment! Thinking about mixins, I rememered about the metacode proposal by D. Vandevoorde to the C++ language. It seems to me that that kind of proposal could serve as basis to many issues you raised...Anonymoushttps://www.blogger.com/profile/04630127186004942157noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-53193425244442370662012-07-17T13:47:57.508+02:002012-07-17T13:47:57.508+02:00Ok now I have a few points on the intent of the ar...Ok now I have a few points on the intent of the article :)<br /><br />My understanding is that a layer, by definition, is an infrastructure (as you discussed back in time). My main experience with this kind of architectures is with J2EE, but actually there is nothing there which constrained layering, and it's too simple to bypass a layer to reach your aim (it happened quite often in my experience).<br /><br />But my intuition is that layers should isolate services which present themselves as cohesive entities. Such as virtual memory, as in your example. A "Business" layer doesn't seem so cohesive as virtual memory, does it?<br /><br />It's intriguing the asymmetry between separating artifacts and runtime entities. My UML skills could be rusted (it's 4 years or so I haven't seen a single UML digram, besides on your blog), but I can't remember of a way for visually representing this kind of relationships between artifacts and runtime objects. Have you found a good one?<br /><br />I'm realizing (very slowly) all of the entanglement stuff. But until you get to the "code"-level, there's always something that escapes me. Maybe it's just a matter of experience, but I didn't get the creation problem until you've shown some code. Do you manage to spot entanglement before you code? Which "tools" are you using?Anonymoushttps://www.blogger.com/profile/04630127186004942157noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-91388982826578817652012-07-14T12:10:02.432+02:002012-07-14T12:10:02.432+02:00Stefano: absolutely, that was on my "table of...Stefano: absolutely, that was on my "table of contents" from the very beginning. I think it would also be interesting to "disassemble" current design principles, and see how they can be explained and easily extended once we understand what they're saying in terms of forces. For instance, the open/closed principle is usually expressed in terms of classes and polymorphism, but it doesn't have to. Another chapter should deal with known patterns, and how they reach some balance between forces.<br />Then, in practice, I'm juggling a number of things, and this stuff is unpopular as ever :-), and before we get to that level, I should at least explain entanglement, spin, isolation etc, so yeah, it's going to take a while :-(Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-6244695968111308482012-07-14T11:52:04.026+02:002012-07-14T11:52:04.026+02:00Matteo:
the elegant solution(s) that you use to ...Matteo:<br /><br /><i> the elegant solution(s) that you use to avoid stupid objects in a layered architecture are not needed in my preferred style of architecture; I just wondered if you agree on this.</i><br />-- <br />sure, with the consequences I've outlined. I want to stress the fact that I'm not pushing an architecture, I just want to make assumptions, choices and consequences <b>explicit</b>.<br /><br /><br /><i>And understanding this technique is prerequisite for your next post. </i><br />--<br />Actually, my next post will simply sort of assume that you can ask your repository and get back domain objects. In your style, that's not an issue to begin with. In other cases, that's regarded as an issue. I just wanted to turn that into a non-issue even for those who want a strong layering. I also wanted to talk about stupid objects and mapping. Funny enough, in the last few days I've been consulting on a project where we settled for an architecture quite similar to this, then another mapping issue arose on the presentation layer, thanks to some short-sighted design in microsoft MVC. I'm glad to say that we overcame the issue, ending up with a more elegant, flexible, faster and mapping-free solution. Of course, we had to try, to spend time, <b>we had to want it</b>. This is where people usually stop. The stupid object, the mapping, is so much easier, brainless, it's like a siren song to most :-).<br /><br /><i>What I'm really curious about then is the followup to your previous post; one design problem I feel about is how to deal with instability in the attributes of domain objects. I wonder if you're going to talk about this next and I'm curious about what your going to say :-)</i><br />-- <br />as I said to Fulvio, the conclusion might actually be rather anticlimatic. I just want to share with you guys something I "see" in the force field of those instable objects, and take the chance to talk about stability / instability in a larger context. Don't expect too much :-)Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-6562406827963571852012-07-14T11:15:33.580+02:002012-07-14T11:15:33.580+02:00Manuel: I can't say much about Scala other tha...Manuel: I can't say much about Scala other than it looks interesting on paper, because I've never used it myself. It surely has quite a few interesting features, and of course is lacking a lot of other features that I consider interesting as well in a truly multi-paradigmatic sense.<br /><br />On the JVM side, I have spent quite some time playing with AspectJ, but then again, more into an exploratory mode, to probe the new limits of the design space. When you move back to professional programming, many other issues arise, and I tend to be a bit more conservative with languages and tools, while probably bold on design choices.Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-45583481446080296442012-07-14T11:07:03.695+02:002012-07-14T11:07:03.695+02:00Fulvio: I'm not inventing much on that side as...Fulvio: I'm not inventing much on that side as the concept of mixin has been around for a long time, and more recently has also been explored in the context of AOP. In a true multi-paradigm language, I'd also like to mix-in things at run-time, much like you can do (for instance) in javascript. While the traditional "confrontational" approach between language schools tend to see static and dynamic typing as adversaries, I simply see them as different materials, with different properties, to be used in different contexts (even inside the same application - usually not toy applications).<br /><br />(observer etc) The interception mechanism underlying most AOP implementations could be used, of course, to implement */*-entanglement on the run-time side. However, in a language truly inspired by the physics of software, this should be more like a first-class concept. Although I haven't given this any serious thought (as I'm still struggling with concepts at what I consider a pre-verbal level), I would probably start with a review of data-flow languages here, because data-flow is a direct expression of <b>some</b> forms of entanglement.<br /><br />Instance/class name: yeah, sort of, or an operator new on steroids if you want to look at the mechanics of it. From the physics of software perspective, while polymorphism allows one to break some forms of entanglement on the artifact side, the need to hard-code class names has always been a strong limit - that's why we have "creational patterns", or more exactly "creational problems" as those patterns are, in most cases, coping techniques.<br />This is one of those cases where I see a strong similarity with Coplien/Liping's idea of symmetry.Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-4386579155270167162012-07-11T12:53:02.912+02:002012-07-11T12:53:02.912+02:00Have you ever considered, at some point in this Ph...Have you ever considered, at some point in this Physics of Software series, delving deeper into the implications your theory has for language design? You don't have to go as far as designing a full-blown programming language of course, but it would be interesting if you could explain in more detail how you would improve on existing languages, and maybe illustrate that with pseudo-code snippets and a few real-world examples. Apart from it making an interesting reading, there's always the chance that someone, someday, somewhere might actually implement your ideas in a real language. But if you don't get those ideas out first, that's bound never to happen...Stefanonoreply@blogger.comtag:blogger.com,1999:blog-13967713.post-77952627897020842182012-07-10T16:23:44.254+02:002012-07-10T16:23:44.254+02:00Hello Carlo,
What I'm trying to do is underst...Hello Carlo,<br /><br />What I'm trying to do is understand what you mean. There's a big gap between what you know and what I know. My reaction to your post is that the elegant solution(s) that you use to avoid stupid objects in a layered architecture are not needed in my preferred style of architecture; I just wondered if you agree on this.<br /><br />But this argument is largely out of topic wrt your post, and it certainly would take too many words in writing while I'm sure you could explain away my doubts to me in a few minutes if we met face to face. So forgive me if I insisted.<br /><br />The big picture I get from your post is that the "obvious" layered architecture has many nonobvious implications that most programmers either ignore or "fix" by writing tons of boilerplate objects. And that if you're careful, you can manage to write meaningful objects even within these limitations. And understanding this technique is prerequisite for your next post. <br /><br />What I'm really curious about then is the followup to your previous post; one design problem I feel about is how to deal with instability in the attributes of domain objects. I wonder if you're going to talk about this next and I'm curious about what your going to say :-)xpmatteohttps://www.blogger.com/profile/16626755265235840659noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-36691476827962833702012-07-06T10:35:49.964+02:002012-07-06T10:35:49.964+02:00Following the idea of design as shaping a material...<i><br />Following the idea of design as shaping a material, my ideal material should provide many different properties, most likely coming from support for different paradigms. While a minimalistic language would push me to create everything out of glass, I’d like to choose between steel, glass, concrete, marble, wood, etc, depending on what I’m building, the surrounding forces, etc. <br /></i><br />---<br /><br />Carlo, I'm curious about this one (among other things, but for them I have to think throught them). <br /><br />What do you think about the Scala language? It's gaining traction in the industry and it's multi-paradigm. To be fair, even Common Lisp is multi-paradigm, but this is another story.Manuelnoreply@blogger.comtag:blogger.com,1999:blog-13967713.post-39376396425634589752012-07-05T20:27:00.378+02:002012-07-05T20:27:00.378+02:00Carlo, I know :D! But, even though it might seem, ...Carlo, I know :D! But, even though it might seem, I never ask for a deep insight view, just some good starting point for thinking!<br /><br />My understanding is that you want to split a class (as having the same class declared, just to not confuse C++ guys, in multiple files) while its instances are the composition of the entire declaration, right? sort of partial classes on steroids. Or maybe the ability to give different views of the same class without resorting to inheritance or interface implementation. Or have you thought about a different concept from classes to represent artifacts?<br /><br />About the observer, is thinking about AOP, not as a solution, but as a concept close to your idea, right?<br /><br />About decoupling instances creation from knowledge of the class name, I feel lost :D Is it about having a sort of product trader in the language?<br /><br />I'm still reserving question about the intent of this post, I need to focus some things better :DAnonymoushttps://www.blogger.com/profile/04630127186004942157noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-49349079228035344852012-07-05T18:00:12.742+02:002012-07-05T18:00:12.742+02:00Daniele:
I understand this post is about making a ...Daniele:<br /><i>I understand this post is about making a true layered architecture withouth using stupid objects (I also guess a layered architecture wouldn't be your first choice, am I wrong?)</i><br />--<br />Right<br /><br /><i>What I don't like very much in your solution is the interface UserData: isn't it a "dumb" interface that provides only getters and setters?</i><br />--<br />Yes, it is. Sure, there could be the usual validation behind that, as the real implementation is inside a business object. But as I said, once we choose technology as a layering dimension, we accepted the idea that layers will be entangled on the structural aspect of the problem domain. That interface is here to remind us that. It could be split in two (read/write), but there is no way around it, unless you resort to dynamic objects and make it implicit.<br /><br /><i>Even its name makes me ring a bell: UserData seems to me an "implementation name". Why it's acceptable in this context?</i><br />--<br />I would actually welcome a better name, but the idea is that it represents the structural / data part of the object. UserStructure doesn’t look much better, does it? :-) Unfortunately, many names are “taken”, that is, have already been used with different meaning in the database-oriented system literature. Considering that in many cases (but not always) we have a corresponding database table, and that before being a table it could have been an Entity in the E/R model, it would make sense to call it UserEntity (which is why, I guess, this name was chosen in some Microsoft-friendly circles for DTOs). It would cause a little confusion (also in the DDD circles), so I’m a bit wary suggesting that naming. In one project, the team chose Plain as a prefix, so we have PlainUser (data) vs User (business). In another project the team pushed for a naming convention so ugly that I can’t even repeat it here. Bottom line: I’m totally open to suggestions :-)Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-35021434255834722352012-07-05T17:43:37.755+02:002012-07-05T17:43:37.755+02:00Fulvio, you have this habit of asking questions th...Fulvio, you have this habit of asking questions that would take 4 books to answer :-). I’ll take this chance, however, to expand a little on my answer to Kevin. I understand the fascination with “pure” and “minimalistic” languages, say the LISP family. I’ve been through that too, may years ago, although I remember coming to LISP with great expectations but in the end finding ML much more inspiring. At some point in my life, after the usual CS exposure to functional programming, concurrent programming, CSS, CSP, etc, I’ve actually designed and implemented a small concurrent language, inspired by the minimalistic CSP approach. We were still in the 80s, and I made that working on single-tasking MS-DOS by [ab]using interrupts, of course. That was a long time ago. I no longer consider that kind of language interesting for practical applications, although minimalism is still interesting inside a teaching environment.<br /><br />Following the idea of design as shaping a material, my ideal material should provide many different properties, most likely coming from support for different paradigms. While a minimalistic language would push me to create everything out of glass, I’d like to choose between steel, glass, concrete, marble, wood, etc, depending on what I’m building, the surrounding forces, etc. <br /><br />“Supporting” the concepts of the physics of software requires, however, that we provide ways to express and to break entanglement (this is interestingly similar to what Coplien and Liping said about providing ways to create and break symmetry). A direct expression of entanglement is the ability to say that I want something to happen when an object changes, or when it is created or deleted. Several patterns (like, of course, the observer) emerged directly from lack of native support for that, and wrapping everything into Observable things is ugly and only works with change, not creation, etc. Providing ways to break entanglement means, in my current understanding of things, mostly breaking entanglement on the artifact side while maintaining it on the run-time side. So, for instance, mixins allows that, AOP allows that, OOP allows that, generics allows that, reflection allows that, etc etc, but they all do in a rather ad-hoc way, as no one has ever considered the problem as I just stated it. Again, many patterns (like all the creational patterns) and tools (the infamous IoC) are born directly out of native support for this kind of things.<br /><br />I should add that I do not consider “purity” as an interesting design concept because I’m interested in real-world languages, not in teaching devices, and pure languages have a bad record when they make contact with the real world. For instance, one may start with the “pure” notion of functions and statelessness (with “pure” meaning “I didn’t get the idea from the real world but from math, so it must be pure”), and then realize that unfortunately the world is stateful, come up with notions like monads and the like and take great intellectual pride in that, as those without proper CS education will fail to master his pure concepts. Having proper CS education :-), I still see that and think “this is just artificial complexity coming from negation of reality”. <br /><br />Ok, I guess I pissed off enough people for one post, so I’ll just stop here :-).Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-71525196037970121052012-07-05T15:26:44.332+02:002012-07-05T15:26:44.332+02:00Manuel: right on the spot :-)Manuel: right on the spot :-)Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-63875698124187850572012-07-05T15:24:50.533+02:002012-07-05T15:24:50.533+02:00[part 2] Rick’s talk, honestly, is just another ni...[part 2] Rick’s talk, honestly, is just another nice rhetoric exercise. He starts with a vested interest in the functional paradigm. He proposes an appealing concept: that things “doing one thing” are simpler than those “complecting things”, and that we should aim for simplicity. And he moves from there to prove that (guess what) the functional paradigm, immutable objects, etc are inherently superior. As in many rhetoric exercises, the final revelation was already nicely contained in the initial set up.<br /><br />We have seen this style in every field over the centuries. At some point, “physics” was based on earth, wind, fire, and aether (and philosophy and rhetoric to back this up). Medicine was based on bodily humors theory. Etc. And we had fierce battles between schools. Then something happened: people started to actually look at things :-), do experiments, build different kind of theories, etc.<br /><br />Getting back to stupid object + functions. Instead of proposing concepts based on abstract notions of “purity” or artificial separation concocted in our mind, I’ve chosen to look at what is actually happening to software. And what is actually happening is that, despite what gurus say, some things then to change simultaneously, some don’t. And that you can try to keep things apart (like data and functions) but those things will still keep changing simultaneously. And therefore I would say that we should not seek arbitrary separation forced upon us by the gurus of functional programming, but we should seek separation along the natural lines: what tend to change together should stay together, what is not changing together should be kept distant. <br /><br />Combining his words any my words, I propose that if you look at things as they are, not as you wish they were, some things are naturally entangled (complected) and that a mere separation in data + functions is not going to disentangle the two, and will just give you two distant yet entangled artifacts. Still, I also propose that we should avoid entangling (complecting) things that are not naturally entangled, and that we should try different forms and different materials (because they react differently to forces), make sure we understand the difference between entanglement in the run-time space and in the artifact space, etc.<br /><br />I also don’t like much the idea that we can make honest progress by scrapping away everything we have learnt so far, like many are trying to do now with OOP, just as it happened with other ideas before. Indeed, my insistence on understanding forces, reactions, etc stems exactly from a desire to understand what makes things work (or not), despite the paradigm (and of course, within the huge variance of people). Of course, creating a chasm is a much more effective way to become popular :-).Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-76554179759701145812012-07-05T15:23:53.735+02:002012-07-05T15:23:53.735+02:00[part 1] Hello Kevin,
I guess my phrasing was a bi...[part 1] Hello Kevin,<br />I guess my phrasing was a bit unfortunate. What I meant was “I want my repositories to give me back domain objects” (not stupid objects that I then have to map into smart objects). Still, your question gives me a chance to state my point better:<br />- forces are shaping our materials, and decisions are forces, including layering and dependency decisions<br />- strict layering with persistence at the bottom is setting up a very strong/constraining force field<br />- even within that forcefield, we can get rid of stupid objects by understanding the nature of software, and that separation of artifacts (which is where we deal with concerns) does not require separation of instances (which would require copy/mapping)<br /><br />As far as I’m concerned, I try not to set up an overly constraining force field in my projects. I’ve been working on many projects though, and teams have preferences (and icons, and gurus, mantras, etc :-), the layered style is very popular, persistence at the bottom too, and I understand its merits (as I’ve explained to Matteo) without feeling a need to support it.<br /><br />About the dumb objects + functions things: ever since a good guy (thanks Vic) put a reference to my blog in the InfoQ page, that talk has been a constant source of visitors, so I should just be thankful :-). I also like Rick’s humor :-) and the ideas he brought into Datomic. Still, that talk is mostly an excellent exercise in rhetoric. There, I said it :-). I guess that criticizing Martin, Hickey, and a few more gurus in a single post is either breaking a world record or committing social suicide :-).<br /><br />Consider for a moment Martin’s talk. He’s an excellent speaker, and he builds a very convincing argument that just like a blueprint reveals the function of the building, so should our architecture. Then he moves, almost unobserved, to say that the folder structure should reveal the function. And so on. Thanks to his speaking ability, people won’t spend a minute thinking that:<br />- the floor blueprint is just one of the many artifacts in building design; some might not be so immediately connected with function.<br />- software is a material where form and function are more disconnected (Gabriel).<br />- software architecture is more about the internal users (programmers) than end users (Gabriel again, this time on patterns). End users mostly see the UI side.<br />- software architecture and folder structure are quite two different things :-)<br />- etc.Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-55898037212937344232012-07-05T13:08:39.330+02:002012-07-05T13:08:39.330+02:00[part 2]
And if you have different bounded contex...[part 2]<br /><i> And if you have different bounded context, then you can define different repositories, just like you can define different "IoC" contexts. </i><br />---<br />Are you serious? If you leave aside your desire to win an argument, are you seriously suggesting that instead of configuring an IoC context (something like 1-2 lines of code or a reference to a different configuration file) it would be better to replicate the entire repository logic, then probably refactor to a polymorphic solution out of disgust, etc? <br />Again, moving back to the decisions / forces perspective, you should see that here we have a force, a rejection force. Having two different domain objects (in different bounded contexts) is trying to pull apart things down to the persistence layer. You’re just giving up, and duplicating the repository. Then perhaps you’ll try to counterbalance that with implementation inheritance. The “abstract mapper” guy I mentioned was trying to handle the same force with a smaller-scale entity (the mapper), as duplicating a repository seems like a rather big deal. I’m trying to keep that force within the center in which it was born: separation of the domain objects, and nothing more, by adding the polymorphic interface in there (and exploiting the IoC/factory).<br />I can only hope that, if you stop trying to show me that your hexagonal guru knows better, you’ll see the inner dance in each of those choices, how they try to balance forces in different ways, subject to different constraints, within slightly different forcefields set up by previous decisions. That’s the spirit of this blog. Or you can keep pushing your hexagonal thing; it’s your choice :-).Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.comtag:blogger.com,1999:blog-13967713.post-50391771789058013312012-07-05T13:07:48.650+02:002012-07-05T13:07:48.650+02:00[part 1]Matteo,
Generally speaking, I’m not sure y...[part 1]Matteo,<br />Generally speaking, I’m not sure you got the spirit of this post (could well be my fault). My spirit:<br />- Decisions act as forces, including layering decisions and decisions about acceptable dependencies between layers.<br />- Even within the highly constraining forcefield defined by a layered architecture with persistence at the bottom, as proposed by many, we can find a way (at least two, actually) to avoid stupid objects and mappers.<br />- Technique #1 is very cheap and only based on generics; technique #2 will benefit from an IoC, but as I said you can go by with factories.<br /><br />It seem like you just want to win an argument about which architecture is better instead, with the usual rhetoric that goes with that. As I told you elsewhere, there can be no progress in design as a discipline if we keep talking / thinking this way. Anyway, trying to get back to the spirit of forces, choices, etc:<br /><br /><i>calling "Container.Resolve" implies a "IoC" framework and that has a lot of consequences. Calling "new" is much simpler</i><br />--<br />You know, I don’t like design by fear. The IoC has a lot of consequences :-). C’mon. It’s not much different than the C programmer claiming that OOP has a lot of consequences. Maybe you’re thinking about some huge, invasive framework, and we know you don’t like frameworks. But it doesn’t have to be like that. You’re also ignoring the option of using generics. And you’re also ignoring the main point: that the team really wanted persistence to be at the bottom, like many are suggesting. They would have just rejected your idea, and probably used stupid objects and mappers.<br /><br /><i>Btw, wouldn't passing a factory be also an option for making your style work in Java? </i><br />--<br />Of course, I also sort of said so. Also, using a function pointer table is a way to make it work in C. Perhaps macros will work too :-).<br /><br /><i>Likewise, I agree that the style that I propose pushes towards doing objects first, persistence later; that's largely the point for me :-)</i><br />--<br />Actually, within the context of data-intensive applications, I tend to use a very balanced approach. Proper database design needs a lot of attention, and may easily influence the “upper layers”. But once again, you seem to think that I’m suggesting, proposing, endorsing a specific layering. I’m not. I’m just talking about forces, about choices, about possibilities. I’m trying to open new possibilities even within highly constrained environments. You’re trying to remove possibilities and sell your preferred architecture. In this sense, you’re trying to engage me in a battle that I’m not interested in fighting.<br /><br /><i>Other minor points: you can test persistence alone in the hexagonal style (and this is another reason I like it). There is a nice example in a chapter of Growing Object-Oriented Software.</i><br />--<br />Hmm. Let’s leave aside the fact that the “nice example” is based on a wonderful OO design where you have classes like DatabaseCleaner, JPATransactor, EntityManager, EntityManagerFactory (C’mon), CustomerBuilder, etc etc. I said: <i>“they wanted to test, performance test, and stress the persistence layer as soon as possible, and independently of a domain layer”</i>, and your nice example seems to be testing persistence using domain objects (where is that Customer class coming from?)<br />You see, if you stop trying to win an argument and step back to my spirit of looking for forces, you’ll quickly understand that if your persistence layer interface is based on domain object, you can’t test your persistence layer without domain objects :-), and that once you try to do that, as I said, you’ll find useful to have an interface for the domain object (the data access part, at least) so that you can mock it, and that will bring you to the same forcefield as the other guys. Forces are there despite what your hexagonal guru says.Carlo Pesciohttps://www.blogger.com/profile/12652284939993729858noreply@blogger.com