Model, Business Rules and Persistence
I'm having trouble figuring out the best approach for an certain application. I'm not really used to newer architectures that superseded old TLA (three layer architecture), so that's where I'm coming from.
When designing the Model and the DAL for my application (POCO classes, right??), I got the following doubts:
Should my 开发者_如何转开发Model classes only expose properties and implement rule validations? A few years ago I'd implement classes that were analogous to the real world, so if I had a Person who could Walk, I'd create such a method. Now, every sample I check (MVC, MVVM, etc.) have "dumb classes", which expose data and, when required, validate those data. What about complex operations? Should they become, somehow, part of the VM (I doubt this is right...).
When using LINQ to SQL as an ORM mapper, should I expose in the model all the attributes of the entity? For example, most of my entities have an ID column as its primary key. This should be of no concern of the Model or Business, just an implementation detail of my database schema.
If (1) and (2) are false, so the Model should expose complex operations on the classes and not all of the entities attributes should be exposed, how do I create the Model classes using LINQ to SQL and sqlmetal? I've seen some samples that use partial classes to extend the functionality of the schema entities, but that would result in exposing the entity details (since it's just an extension).
If (2) is false, what is the most correct way of using sqlmetal and LINQ as an ORM? I use sqlmetal to extract the schema, LINQ to select entities, and then what? Create new entities based on what I have on the database?
In my researches I found that the VM from MVVM and the P from MVP are somewhat similar. What are the responsibilities of a Presenter? And those of a ViewModel? I'm focusing on those two patterns because they completely isolate the View from the Model, an aspect that I prefer.
What are some methodologies when designing such [MVVM, MVP] applications? Should I begin thinking about the Model, then the {P, VM} layer, then the view? This is more of a subjective question, I know, but examples would be nice.
I hope I was able to make the questions objective enough. I've added explanations to my doubts in order to simplify answering, but I'm afraid this has made the post a little bit too large. Anyway, thanks a lot for reading, any suggestions are very welcome.
Here are some thoughts for you about model design from my experience.
- Relax. No matter what you do in your model design, it can still be open to criticism and complaints from people. You can't please everyone. If you make it totally buzzword compliant with the latest thinking of things, it could be complex, abstract, or hard to understand. On the other hand, if you just slap it together without much rhyme or reason, you can get into trouble that way too. The code is there to serve the application, it's there to make the application get into the done basket in a way that will be easy to read, easy to understand, easy to maintain. A lot of other considerations are secondary.
- What level of exposing to do. The right answer depends on what the future of your app is, and either approach can be a good decision. Something that helps me on deciding what to do with models is to pretend that I'm writing more than one consumer/user/UI layer that goes on top of the models. So typically an app will just have one UI. But pretend that the app is going to have more than one ui-- say both a web UI and a Smartphone actual GUI UI. Pretending that there will be both will help you make decisions to put more and more logic into the models/data access layer, and less and less logic out at the UI layer. If you make your models very thin and expose aspects of the ORM to the UI, then you get tempted to put a good amount of ORM type code into the UI. This can lead to having the code be more schizophrenic. It makes it so that if you ever decide to change backends, say from SQL to another flavor of SQL, or Cassandra, or something else, you pretty much can't.
- Consider using a webservice for your data access. You could put all of your data access into a webservice. Then your UI layer would use the webservice for all data access, both read and write. This sounds a little radical, but it has a number of key benefits.
- It helps you separate the concerns of the UI layer and business logic layer.
- It enables you to add more user interface types later with comparatively tiny effort. You can build tools into your platform (if they don't already exist) that makes doing this very easy, and you may find your code gets smaller.
- It makes it more comparatively straightforward to totally change how your backend works without changing any of your UI code at all.
I've moved an app from SQL to Cassandra in this way. By separating all data access into a webservice, implementing a good test suite for the webservice, then re-implementing the webservice. The app was much smaller and cleaner afterwards.
I think you're worrying about the wrong things. Think of the data access layer/models as providing the ideal services that would make your UI(s) as easy as possible to implement. Envision what this ideal data access layer would look like, that'd make the job easy to do. Stub out that interface, then bring it to life. How it looks on the inside is less important.
The things that are important is that the app must be completed, it must work, and it must be readable and easy to maintain. Personally I wouldn't sweat all the other stuff. Unless a key requirement of your app is that it impresses someone when looked at from the inside, you're worried about the wrong things. Read what other people have to say and use what resonates within you and makes sense, but don't sweat it if what you're reading doesn't seem useful to you on your projects.
In my experience, I've learned that models can become obsolete quickly, especially with increasing detail and complexity. Moreover, focusing too much on developing detailed modeling artifacts can detract a team from delivering incremental value to their customers. Therefore, I recommend that you consider an agile approach to producing models that provides enough detail to the team so they can deliver valuable features to your customers within an iteration of about 2-4 weeks. Take a look at Scott Ambler's Agile Model Driven Development (AMDD) methodology.
精彩评论