in

 

Evan Hoff, Professional Code Junkie

November 2007 - Posts

  • The Shape of the Domain Model

    This is a bit of a random thought which I had this morning regarding the relationship between the domain model and data.

    An instance of the domain model (or parts of it) is a snapshot of the model at a given point in time.  Specifically, the state of the model is the snapshot.  The configuration of the pieces of data in the model is the shape of the domain model.

    If the shape of the domain model corresponds closely to the database schema, changes in the domain model's shape require data migrations in the database.

    It's not earth shattering, but thinking of the model in terms of shape is an interesting concept to me.  Thinking about the evolution of the model's shape over the lifetime of the application is also a cool concept (ie..shape in relationship to time).

  • [Book Review] Enterprise Architecture As Strategy

    Environments where many applications and many development teams must talk have an additional layer of complexity surrounding them.  The more integrated the applications have to become, the hairier it gets.  If this scenario sounds like the company you are at, there's a good change this book will bring some clarity to your world view. :-)

    I would recommend making sure you are familiar with Enterprise Integration Patterns first, however.  Without some decent coverage of different Integration Topologies, it might be a bit hard to grasp the application of the material.

    There were a number of things in this book that stood out to me.  The first was the authors' introduction to four Operating Models: Unification, Coordination, Diversification, and Replication.  The four models correspond directly to the model through which the business works.  It's important to note that the Operating Model is not determined by IT but should be selected during an engagement between IT and the business (sound familiar?) to determine how the business wants to grow and position itself.

    Roughly speaking, there's an interesting correlation between the Operating Models and the various Integration Topologies (Broker, Bus, Point-to-Point, etc).

    There was a lot of focus on how processes differ across companies with different operating models.

    I'm not going to go too deep into the rest of the book's content, but I will say that it was a great read.  It was a bit lighter than some of the other techincal books on my bookshelf, so that was a welcome change.

    If you are interested in reading a bit more on this topic, you can also check out Nick Malik's series of posts on this same book/topic.

  • Fighting Your Tooling Sucks

    Here's a comment from Phil's testability post:

    "I have been working on a project trying to apply these principles and it seems that using the Entity Framework or Linq to Sql, it is hard to have a loose coupling between the UI and the data layer.
    This would require the UI to talk only to interfaces so that the data layer's implementation can be changed easily.
    The designers are very nice, but they don't generate these interfaces, so I had to extract them from the generated classes and make the partial class declarations inherit from these interfaces; this almost looks like a haack.
    The interfaces then have to be kept in sync with the generated classes manually.
    The good thing I realized in this process is that this way, I can overcome the limitation of the designers to put custom attributes on the entities properties (for validation for example), by applying these attributes to the interface's property declaration.
    Or is there a better way to do this? "

    He's another user fighting his tools..

    And all he wanted to do was decouple his UI from Data Access.

    Its too bad that that the tooling took him down the wide/easy road of drag and drop and then left him high and dry when he wanted to do something basic with his design (decoupling).

    One might argue that it's not Visual Studio's fault that he isn't sure how to decouple this stuff, but it doesn't have to be that way.  In my opinion, the tooling should promote good practices (such as decoupling).

  • On Mobile Objects

    It's comments like this that give me pause and make me wonder if I should join this thread... Everyone's gonna call me a moron, but I'm hoping to learn something here.

    You are most definitely not a moron. :-)

    We use mobile objects. (insert flame here)

    No flames from me. No questions are dumb questions. Well actually, I've asked quite a few dumb questions, but this question is *definitely not* a dumb one.

    I've never really understood (and this is simply my lack of experience/exposure) the whole DTO/separate objects on the client/server thing. It seems like extra work to me to have to copy all of the properties from one object to another, just because one object was used to cross the wire and another wasn't. I've tried to get a grasp on this and haven't ever been able to see a "complete" enough example to get why this is beneficial or good design. I'm sure there's a reason - otherwise everyone wouldn't be championing this particular pattern so frequently. I just wish I could see a complete example and "get it".

    It really depends on the scenario. In the "distributed object" context I was referring to, it was really a rail against Remoting style architecture. I can't vouch for the product that Jeremy was describing in his message, but when I think of mobile objects, I think of distributed remoting designs.

    In that particular style of design, you might create an object on the server, and get a proxy to it on the client. The client invokes methods which then actually run on the server.

    The reason those styles of design are bad is that they tend to be very chatty with the traffic going across the network. You can imagine the amount of network traffic required when a property getter requires a roundtrip to the server. This ties directly into the Fallacies of Distributed Computing.
    http://www.lostechies.com/blogs/evan_hoff/archive/2007/10/24/the-8-fallacies-of-distributed-computing.aspx

    That style of design forgets that there is latency going across the network (among other things).

    You might google RPC for more information if you want.

    This is a slightly different topic from DTOs (Data Transfer Objects), however.

    The purpose of DTOs is primarily to decouple layers in your application. They insulate your UI and Domain Model from one another. You typically see it used in conjunction with a Service Layer, where the service layer manages database transactions, manipulates the domain model, and manages the copying of data from the domain model to the dtos. Other people might actually use two layers to accomplish the same thing (see PoEAA for a good discussion).

    Regarding the DTOs themselves:

    As an example, start with a Customer class with Address1 and Address2 fields. Then build the Customer forms. At some point down the road you decide to factor the Address fields on the Customer, User, Supplier, and other entities to use a common class, the Address class. When you perform the refactoring, you also have to fix your UI code (Address1 and Address2 are not properties of Customer any more). That's when the DTO would have stepped in to save the day. You could continue to have the Address1 and Address2 properties on the DTO while modifying the Customer class (and all the others). Your UI code would still bind to the Address1 and Address2 fields on the DTO. The DTO provides a level of abstraction between the layers.

    Another example might be if you have a graph of objects with a complex relationship. You might have a Patient class with a collection of LabValue classes. Each of your LabValue classes references a LabTest (with the Lab name) class. This would be a key scenario to introduce a DTO. You don't want your UI to have to know the complex relationships between these classes, and you don't want to have to change your UI when/if the relationships change.

    In short, use of the DTO pattern is optional (as is the service layer). It's up to you whether you need it for your application or not. It has its benefits, but it also requires additional coding. I pass no judgement on people who don't use it (I know a few people whom I greatly respect that don't use it--even though they are using a full blown Domain Model).

    Another slight variation would be on tiered applications where a client connects to a service somewhere (ie..a webservice running in the application tier). The DTO is actually quite handy in an application running a domain model behind a webservice. If you've ever dealt with ASMX webservices and the XmlSerializer, you know how picky the serializer can be. By decoupling the domain model objects from the WSDL, I gain two things:

    First, if I return a DTO from my webservice (and not a domain object) I decouple the WSDL (the external system contract) from the webservice consumers. This may seem like a minor issue, unless you have webservice consumers who are out of your control (say, an application in another company). You don't want to force them to recompile their app when you deploy a change in your domain model (you can replay the Customer scenario above with Address1 and Address2 to see what I mean). In code-first webservices, the DTO allows you to tightly control the WSDL schema.

    Secondly (and more obvious), it allows you to use things like read-only properties and non-parameterless constructors in your domain model. The XmlSerializer is a bit fragile (for good reasons), so using the DTO allows me to loosen everything up for the serializer, while doing good class design for my actual domain objects (entities, etc).

    In terms of WCF, DTOs make good Data Contracts whereas model objects don't (for the above reasons). Versioning my entities with WCF stuff is a bad idea.

    If anyone wants to send me an email sometime and have a chat about my application's architecture, and explain some of this stuff to me, I'd appreciate it. I don't know if I feel like having my ignorance taken to task in a public setting.

    Kudos to you for asking. Now if only we could get more people asking questions. :-)

    If anyone ever has a direct question for me, feel free to email me. It's been giving me some topics to blog about of late.

  • Building the Application off the Database

    A couple things are bothering me this morning. I had a potential client asking me about IdeaBlade from DevForce as a possible application framework. I looked at their developer's guide for about 15 minutes and it was enough for me to go thumbs emphatically down.

    Specifically, I wouldn't want to touch it because it:

    * Creates the "Domain Model" directly from the database with a designer tool. I've always detested this model. I think it forces or at least tempts you into BDUF. Incremental changes are clumsy when you have to fire up the designer GUI instead of just making a code change. It's easier to do evolutionary design with POCO's than it is to constantly morph the database and regenerate. Lastly, for anything remotely complex I almost always find a reason to make the Domain Model structure deviate from the physical database structure. Locking the two things together almost always lead to one model or the other sucking.

    There can really only be 1 true model. It either exists in the database or in the application. If you generate off the data model, it is the one true model. I have yet to see an implementation that will roundtrip between the two--ie..generate off the data model but then update the data model off app changes. Without roundtrips, it just reinforces the "one true model" stigma.

    You can see the same problem with code generation. If the code generation doesn't support roundtripping, the templates basically have to become the "one true source" that you work with and around (partial classes, etc). They become the central driving concept in development.

    My personal opinion is that you are better off realizing what the one true model is and not fighting the current. That's also why I really don't enjoy generating the app off the database. I much prefer making POCOs the one true model.

    In the "one true model", you do have to make compromises so that you don't trash the other model all to hell, but that's about the best I've found you can do. After you learn one modelling paradigm (or both) really well, the incompatibilities really start to show.

    In short, I agree with you--although it's not an argument of BDUF to me. It's an argument of how I choose to work and where I find the most power lies (for tackling complexity with the least amount of effort and greatest robustness/agility to change).

    This argument also has built in assumptions though. I'm assuming there is complexity or a high rate of change. If an app invalidates those assumptions, my argument has no wind (and I would reevaluate my tooling). For example, without complexity (Forms over data), the two models can basically be mirror images.

    I want to say that this type of "spit out an application" to match the database is only useful for simple CRUD apps, and not very many systems really fit that description.

    Agreed, unless the developer is more DBA than programmer. ;-)

    * It's an ActiveRecord approach and that still bugs me to have data access stuff jumbled up in my Domain Model. I know that argument never dies, but is it really that hard to use NHibernate like ORM's with a Unit of Work?

    No. It's not. (Oops. Was that rhetorical?)

    * Mobile Objects: I bump into this from time to time. The idea that systems are easier to build if the same set of domain objects can run on both client and server. It saves duplication on validation and that's cool, but the idea of running the same domain model on both client and server smacks of very tight coupling to me. This DevForce thing, Astoria, CSLA.Net and whatnot just smell wrong. I say that the domain model should follow from behavior, not data structure, and the behavior could easily be different from client to server side. When I've seen CSLA stuff running on the server side the code looks way too busy because of all the extra StartEdit() blah, blah stuff that's there for running on the client side.

    I'll defer to Fowler on this one. To quote him:

    Fowler's First Law of Distributed Object Design:
    Don't distribute your objects!

    Or to pull a more choice quote, "this design sucks like an inverted hurricane".
    http://www.ddj.com/architect/184414966

    I'm not a big SOA fan, but having some loose coupling between a desktop client and the backing services is just plain good fundamental design.

    Screw SOA. It's just good design.

    What do you guys think? Am I being too harsh, or not being open minded? I really don't want anything to do with this kind of solution but you never know...

    You don't have to give yourself a lobotomy to be open-minded.

    Why are they picking this tool in the first place? Does it give them a strategic advantage over their competitors? If there's no business reason, they should be having a conversation with you (the expert) on what you know works (and what you know can be effective when building the app). If that's the case, tell them to put the shiny thing back in the store window where it belongs.

Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems