In MVC, MVVM, or MVP I typically have models that either put a heavy emphasis on using other models in conjunction to get the full set of data needed or that basically require joins to other tables (models). When I run into this I usually just extend the model's functionality like normal but will include a join to another table in new method I'm creating. What's tricky for me to sometimes decide is which model I should put this functionality/join in since it makes it dependent on something not specific to that model. Is there a better way of dealing with relationships when using patterns that utilize data models?
Here is some pseudo code to help illustrate what I mean with some active record mixed in:
public static void getAll() {
this.db("sometable").join("anothertable", "column", "=", "anothercolumn").select();
}
Now if the model was for sometable I'm creating a dependency of sorts by joining to another table in the method above. Now the model for sometable also deals with anothertable which would have its own separate model.
'Model' is an abstract term. It doesn't need to be one single model.
I look at MVP as a presenter, a view and whatever else I need to get the job done. This might be one class, an enumeration or a number of repositories. As long as I keep my presenter's dependencies low, I'm happy.
Could you consider making your controller or presenter dependent on something 'above' your models that can get related things as, and when, you need them?
Related
In my organisation we have a complex product card with lots of different properties. I could use Steam product card to visualize what I'm talking about: http://store.steampowered.com/app/219740/ (PS: Awesome game, check it).
Product card representation consists of properties such as title, description, price and associations like screenshots, reviews, ratings, tags etc.
Segments of product are used in different parts of application - for example you can find tag lists in user library (where you don't need screenshots).
How would you structure read model here?
a) Try to create small, generic view models (Screenshot, Tag) and composite them in concrete view (ProductCard, UserLibrary)?
b) Create one, god Product view model that'll contain every property that is related to product? (performance-wise - doesn't sound very good)
c) Create property tailored view models for each view? If so, how can I avoid code duplications (we use parts of product on EVERY page) if I have to re-use some specific parts (product title, price etc) all across application?
d) ?
I cannot use event listeners as projectors since product state is changed via legacy CRUD application which we cannot modify - we rely on shared database.
The answer is...
Create property tailored view models for each view
Why? Because it's the simplest and the most maintainable solution. In a read context, you're just dealing with read-only data. You don't need encapsulation or granular representation (a specific model for 'Screenshot' or 'Tag'). That doesn't mean you can't reuse any of the other view models if you already have them and they have the same data, but the main principle here is to create a view model to serve a particular view only.
Duplication doesn't exist in this context, because DRY refers to (same context) behaviour not data.
Why do you want to avoid code duplication ? Or more specifically why do you want to avoid code duplication in different bounded context ;)... If you create dependencies only based in avoiding code duplication you will create a wrong abstraction (not related to a valid use case).
I will quote Sandi Metz :
duplication is far cheaper than the wrong abstraction
prefer duplication over the wrong abstraction
Find more here about wrong abstraction
I'm working on a website with a few colleagues and we are having some differences in how we see the class architecture so I'm posting this too see how the larger community feels about this issue because I presume a lot of people were in a similar situation.
We are using an MVC approach with model implemented through active record pattern. One of the models is the "Product" model related to the product table in our database.
The thing is, we have two main types of products - tangible ( type = 1 ) and non-tangible ( type = 2 ). Throughout the code, we'll have tons of logic related to just this - type of product. ( if tangible do this, if non tangible do that...)
So one approach is - create classes TangibleProduct and NonTangibleProduct and through a factory fetch one or the other. Of course, these classes would have duplicate methods i.e. isTangible() or isNonTangible() would exist in both classes but in one case would return true an in other would return false. (this is just an example ).
I'm expecting to see at least about 30 different methods in classes which will return different values based on product type.
The other approach is to have just one Product class and in each method implement IF blocks and do the logic if product is tangible or non tangible and return results.
I know this is a vague question but I do think that most of the people who are working in an OO environment had a similar situation at some point...
Do you see any long term consequences in choosing one approach over the other, do you see any approach better or worse than the other?
Editing:
Sorry, I might have not been too clear. These two classes would extend the Product class. (i.e. "class TangibleProduct extends Product" and "class NonTangibleProduct extends Product" )
Thanx
Architecturally speaking, since the difference between tangible and intangible products is so fundamental in your domain the best approach is to have separate classes TangibleProduct and IntangibleProduct and handle both as instances implementing IProduct (a variation on the first approach). If your ORM tool allows you to do this then it's all good.
The second approach should be avoided very very hard.
It's generally advisable in OO to have this sort of distinction made in a class hierarchy.
If you use a factory method to create the right subclass, you only do the conditional logic once at creation time instead of in each method where the behavior varies.
You can also more easily add a new type. If the decision logic is repeated in many methods, you have to change them all. If it's consolidated in a factory, you only have to add a branch there and implement the new subclass and all the existing subclasses can frequently be untouched.
It's hard to tell without having access to your full requirements.
It mostly depends on whether there will be any non-trivial methods which
behave very differently for tangible and non-tangible products.
only make sense in the context of tangible or non-tangible products.
When you end up creating a lot of methods which look like this:
public void doSomething()
if (isTangible) {
[...loads of code...]
}
else {
[...loads of different code...]
}
}
you would be better off with separate classes.
I need some help as I seem not to be able to grasp the concept.
In a framework, namely Yii, we create models that correspond to database tables. We extend them from CActiveRecord.
However, if I want to create a class that will get some data from other models but then will do all the computations based on those results and do something with them... then how do I proceed?
I want to clearly divide the responsibility so I don't want put all the calculations in source db based models. Basically the idea is that it will be taking some stuff from some models and then updating another models with the results of the calculations.
What do I do?
Keep all the calculations in some controller and use required models? (Hesitant about this because there is a rule to keep controller slim)
Create a none db model and then work from there (how?)?
Do something else (what?)?
Thanks for any help!
For you to use the Yii interpretation of Model, you will have to create class, which depends on CModel. It is an abstract class, thus you will be required to implement attributeNames() method.
To use other "Models" with this new structure, you will need to inject them in constructor, or right after your custom model has been created.
In real MVC model is a layer, which mostly contains two sets of classes with specific responsibilities: domain business logic and data access operations. Objects which are responsible for Domain Business Logic have no clue where the information is stored and where it comes from. Or even if there is such a thing as "database".
This video might explain a bit: https://vimeo.com/21173483
I am creating view models for each screen in my ASP.NET MVC application. I put all of the logic for creating a view model in a builder class. Usually, there is special logic for converting the data objects into view models, including aggregating, filtering, and sorting. Each builder is passed a dependency set, which is an object containing properties for each dependency (repositories, other builders, etc.).
The problem is that my names are getting really long. A dependency set will usually have a name composed this way:
view-model-name+Builder+DependencySet
View models usually have names composed of where you are currently and the children. For instance, my system has categorized provider definitions. So, in order to show the provider definitions under a category, I have a view model called:
CategoryProviderDefinitionListViewModel
It will look something like this:
public sealed class CategoryProviderDefinitionListViewModel
{
public long CategoryId { get; set; }
public string CategoryName { get; set; }
public ProviderDefinitionViewModel[] ProviderDefinitions { get; set; }
}
So, my builder is called
CategoryProviderDefinitionListViewModelBuilder
So, my dependency set is called
CategoryProviderDefinitionListViewModelBuilderDependencySet
That barely fits across the screen. My poor fingers are tired. Furthermore, some screens almost show the same data, so their view model names are almost the same. When I am looking through my folder, it becomes really hard to find the specific view model classes I am looking for.
Ideally, I could group my view model classes together, associating them with the view(s) where they are used. It would be nice to avoid collisions and to make names as short as possible, while keeping them meaningful. Has anyone found a naming convention/folder organization that works well in this scenario?
I've been using the "ViewModel" suffix consistently for quite a while and to be honest, sometimes I find it redundant. I think just grouping all these classes in a different namespace should be sufficient.
My understanding is that this convention has been adopted to avoid collision between domain model and view model classes (eg Product vs ProductViewModel). However, since your view models are named after the screens, it is very unlikely that you would have a class with the same name in your domain model. In fact, it should be really questionable why you have such a class in your domain model! :)
So, if you name your view model something like ViewProduct (to allow the user to view/edit a product), you don't need to call it ViewProductViewModel. See where I'm going?
Consequently, your Builder class could simply be called ViewProductBuilder instead of ViewProductViewModelBuilder.
Regarding your dependency set, I'm not sure what is your rationale behind this. But to me it looks unnecessary. If your builder has dependencies to other objects, you'll need to inject dependencies in the constructor of builder, instead of encapsulating them into another class (DependencySet) and then passing them around.
If you find your builder dependent on too may things and this is what you are trying to hide behind DependencySet, then it could be the indication of a design smell somewhere else. If classes and their dependencies are designed in a proper object-oriented fashion, behavior should be distributed very nicely between various classes and no class should have dependency on too many other things. So, hiding those N dependencies under 1 class (DependencySet) is merely treating the symptoms not the problem itself.
Hope this help :)
I prefer post-fixing my ViewModel names with "DTO". (Where DTO stands for Data Transfer Object, ie. an object that does nothing but contain information)
This is not only to avoid long names. But it also makes me able to use the same names like User, but it will be called UserDTO, indicating to me that I am working with an object that is part of my ViewModel, and thus avoid naming collisions.
I tend to agree with Mosh.
The ViewModel suffix becomes redundant the majority of the time and while sometimes you might have matching class names, it is quite easy to manage as they are confined to your ViewModel namespace. I also find that using the odd namespace alias hurts my brain less than suffixing my class names across the board.
Of course in your presenter/controller you may have naming collisions, but that could be a sign that you need to name your Views more appropriately, e.g. not User but ViewUser/EditUser.
For search results and lists I find it is best to break out something such as IEnumerable instead of IEnumerable. The latter often means you end up with a User view model class that becomes a dumping ground for all User properties that may or may not be needed across the project. This is one of the big things to watch out for and if you find yourself with a class like this, you've gone of the track somewhere. Keep your views and view models descriptive and specific. If you have many similar view models the issue is probably a bigger design problem; some designers have a tendency to reinvent rather than reuse existing graphical structures.
I'm writing an application to help diabetics manage their condition. Information that is tracked includes blood sugar results, nutrition, exercise, and medication information.
In similar applications these entries are all presented in a single table view even though each type of entry has different fields. This data is manually tracked by many diabetics in a logbook, and I'm looking to keep that paradigm.
Each entry has some common information (timestamp, category, and notes) as well as information specific to each entry type. For instance, meal entries would have detailed nutrition information (carb counts, fiber, fat, etc), medication entries would indicate which medication and dosage, etc.
I've considered two different approaches but I'm getting stuck at both a conceptual level and a technical level when attempting to implement either. The first approach was to create an abstract entity to contain all the common fields and then create entities for each log entry type (meals, meds, bg, etc.) that are parented to the abstract entity. I had this all modeled out but couldn't quite figure out how to bind these items to an array controller to have them show up in a single table view.
The second approach is to have one entity that contains the common fields, and then model the specific entry types as separate entities that have a relationship back to the common record (sort of like a decorator pattern). This was somewhat easier to build the UI for (at least for the common field entity), but I come to the same problem when wanting to bind the specific data entities.
Of course the easiest approach is to just throw all the fields from each different entry type into one entity but that goes against all my sensibilities. And it seems I would still run into a similar problem when I go to bind things to the table view.
My end goal is to provide an interface to the user that shows each entry in chronological order in a unified interface instead of having to keep a separate list of each entry type. I'm fine with adding code where needed, but I'd like to use the bindings as much as possible.
Thanks in advance for any advice.
Don't get bogged down with entity inheritance. You shouldn't use it save duplicate attributes like you would with classes. It's major use is allow different entities to be in the same relationship. Also, entity inheritance and class inheritance don't have to overlap. You can have a class inheritance hierarchy without an entity inheritance hierarchy.
I'm not sure I understand exactly what you really need but here's some generic advice: You shouldn't create your data model based on the needs of the UI. The data model is really a simulation of the real-world objects, events or conditions that your app deals with. You should create your data model first and foremost to accurately simulate the data. Ideally, you should create a data model that could be used with any UI e.g. command-line, GUI, web page etc.
Once your model is accurately setup, then whipping up the UI is usually easy.