I am learning MVVM now and I understand few things (more than but few are here..):
Does every model potentially exposed (thru a VM) to the View is having a VM?
For example, if I have a Contact and Address entity and each contact has an Addresses (many) property, does it mean I have to create a ContactViewModel and an AddressViewModel etc.?
Do I have to redeclare all the properties of the Model again in the ViewModel (i.e. FirstName, LastName blah blah)? why not have a ViewModelBase and the ContactViewMode will be a subclass of ViewModelBase accessing the Entity's properties itself? and if this is a bad idea that the View has access to the entity (please explain why), then why not have the ViewModelBase be a DynamicObject (view the Dictionary example # the link page), so I don't have to redeclare all the properties and validation over and over in the two tiers (M & VM) - because really, the View is anyway accessing the ViewModel's fields via reflection anyway.
I think MVVM was the hardest technology I've ever learned. it doesn't have out-the-box support and there are to many frameworks and methods to achieve it, and in the other hand there is no arranged way to learn it (as MVC for instance), learning MVVM means browsing and surfing around trying to figure out what's better. Bottom line, what I mean by this section is please go and vote to MSFT to add MVVM support in the BCL and generators for VMs and Vs according to the Ms.
Thanks
What a telepathy!
I enjoyed so much reading this great article of Robert McCarter's, he talked just about what I felt painful with! especially about the proxy-properties (now I even know it's name...).
I would warmly recommend this article to every MVVM confusee (like me - I am sure there are a lot!)
1/2) Like with most programming problems... It all depends.
It depends upon how you've linked together the ideas. You can re-expose the needed model properties in the view model if it fits your needs. Hide model proporties that you don't want the user to interact with like a DB key. You can put the model validation logic in the model or the view model. It all depends on what works for you and your situation, which is why it is hard to directly answer the question.
I am using the ViewModelBase for functionality shared by ALL of the ViewModels. I've been using the base object to handle INotifyPropertyChanged code and little else.
3) Take a look at Karl Shifflett’s web site. Karl has a bunch of code you can look at. Stuff and BBQ Shack are working MVVM projects. He also has a complete MVVM training module here.
I'd post some links, but I'm limited to 2 links per post.
Related
I have the following folder structure for my application
app
core
features
feature1
domain
entities
entity1
entity2
entity3
entity4
entity5
entity6
data
models
model1
model2
model3
model4
model5
model6
presentation
feature2
domain
entities
entity1
entity2
entity3
entity4
entity5
entity6
data
models
model1
model2
model3
model4
model5
model6
presentation
Model 1 to 6 for both features are exactly the same and more are coming as the application scales. This is becoming hard to maintain. Does clean architecture allow for sharing models and entities across the multiple features? Would that be done through the core folder?
Yes you can and you maybe should not do it.
Yes, because the clean architecture doesn't make a statement about this. As long as the dependency rule is honored you are compliant in terms of the clean architecture.
But you maybe should not do it, because there are other principles and considerations you should take into account.
First, you should ask your self if it would be a violation of the single responsiblility principle. Sometimes things look the same but are not really douplicated code. It's more an accident that they look the same. The question is "Who is the change trigger?". Usually the features change for different reasons and thus the features use cases and entities change for different reasons. If so you should not share the models between them.
Second, from a DDD (domain driven design) perspective the features can be in different bounded contexts. In this case you can have two entities with the same name, but they have different meanings in the differnt context. Therefore, the models have different properties and different methods.
If you decide to share the modles you should take a close look at them in intervalls and scan the properties and methods. Are there properties and methods that are exclusively dedicated to one feature? If so you are maybe mixing concerns.
Finally if you are facing problems like "Uhh, we changed someting here and broke something there", you should rethink if the sharing of some code is a good way to go. Sharing of code always couples code, because all clients depend on the shared code. It's a trade off between duplication (maintenance costs) and dependencies. Principles like the SRP help you to make an educated guess.
Does clean architecture allow for sharing models and entities across the multiple features?
I think DRY principles should be applied whether you use clean architecture or not.
As for the answer:
I think you could abstract your shared models and entities into separate modules or packages. If it's all dart code, I suggest choosing packages. You can place it inside the root project (Monorepo) or separate it to another repository, this way you could achieve modularity by abstracting the all layer of shared dependency (abstract class, interface, clients, or maybe repositories) out of the main application
There is a good video about this topic on Google I/O'19, it is about Android but you can get great insight and applied to general mobile development. I suggest you give it a try
I'm assuming you're following the ResoCoder course. I did too. I used that design in our team for a few weeks before realizing there soon become problems with it (which ResoCoder himself realizes if you check the Github issues and responses for his repo):
Sharing between features doesn't work well.
It's hard to have functionality split between multiple features.
Not well organized with a lot of code.
Some more which I forget off the top of my head (He wrote some article on the failing of it somewhere).
Hence, for my team's app (getting quite complex now), we've adapted this which seems to work:
(ignore the 2 \core directories, that's by mistake. There's meant to be only 1)
Then, inside all of these top-level directories (excluding /core - that's specifically for things like API clients, routers, etc.), there's folders for each feature. Ex: authentication, settings, posting, etc.
Then, here's the important bit, in each of these feature-split directories (ex: /domain, /presentation, etc.) we have a sub-directory called /shared that resembles what each folder needs to look like, except it just contains functionality that's categorized as (example) domain or data. This stuff is then split between all features.
For example, if I have an app that allows users to post content, I'm going to create the post entity (using ResoCoder terminology) inside the /posts feature. Except, UH OH, I need to have it displayed inside the /feed feature as well! This is then a perfect case for /shared inside the general /domain directory.
Let me know if this helps, or if you have any further questions!
We are working on a bigger project with Ruby on Rails. As you might know, Rails works with MVC pattern and typically enforces the following class types for Domain objects:
Controllers (+ Helpers)
Models
Views (e.g. erb)
Serializers
Mailers
We experienced - like many other teams - that this is not feasible for bigger, long-running projects.
So in our current project, we added some layers, so we typically have
Controllers (+ Helpers)
Policies (access control per controller)
Presenters (a.k.a ViewModel)
Forms (containing all attributes available in an HTML form)
Views
Models
Queries (static ActiveRecord queries)
Serializers
Mailers
Services (Domain Service which extracts business code from controller)
It is much more testable, maintainable and understandable.
However, our boss disagrees with "These are too many classes".
As he is typically a proficient architect (doing consulting), I don't want to simply reject this response. However, his time as active Java developer are gone and he often explains such sentences with his improved "gut feeling".
Of course, there are metrics that count classes - but is there a general approach to classify something like 'Classes per Domain object' or 'Class per Business case', which can be taken for an argument?
I have never heard of a rule or best practice which limits a number of classes per project, domain or whatever. One should create as many classes as he REALLY needs. The key word here is "REALLY" because quite often developers over complicate things and create unnecessary classes, layers or even tiers. Without the details about your project I suggest you do the following:
Ask your boss to elaborate on the "Too many classes" phrase. Ask for his concerns. If he is a good architect and a team member he understands his responsibility of coaching people.
Make sure you clearly explained to him why you needed those classes. Provide examples.
If your boss is stubborn, his best days as a developer are gone and he just wants to show his significance, remind him about his responsibility for a successful project. For example, tell him he is an architect and a person who makes the final decision and you will follow it because he is the one who is responsible for the project success but on the other hand it's your responsibility to be proactive and express any concerns you have to help your boss make the right decision. This should make your boss think again as he doesn't want to fail the project because of his "gut feeling".
Hope it helps!
In the special Window 8 edition of MSDN Magazine (http://msdn.microsoft.com/en-us/magazine//jj651572.aspx), Laurent describes initialize his SimpleIoc container, and also describes how to implement navigation from the ViewModels using a NavigationService, which implements INavigationService.
However, in Figure 6, (which he says illustrates how to register the service), his code snippet clearly refers to a design-time NavigationService, named DesignNavigationService, which I presume is to support "Blendability" (Laurent is very big on supporting Blend, and I appreciate that).
Does anyone know what is different about a design-time navigation service? There's no other mention of it in the article, and a few Bing searches turned up nothing useful.
Found the answer in the sample code that was published in conjunction with the article.
In the DesignNavigationService class, there's this explanatory comment:
// This class doesn't perform navigation, in order
// to avoid issues in the designer at design time.
Which, given that the ViewModel classes may be running a little bit at design time, makes sense, now that I think about it.
can somebody explain me the basics of mvc in iphone apps?
I see the template classes, but how do they communicate?
does UIView send events to the Controller? or does the model send events?
what of the template files is the model?
I would strongly recommend the iTunesU, Stanford University series titled "Developing Apps for iOS (HD)" by Paul Hegarty.
Lesson 1 discusses MVC and lesson 2 demonstrates it.
These lessons are free, and well worth a view if you have the time.
The model shouldn't be concerned with the view. The same holds true for the view, it should be decoupled from the model and not really have direct access to it, despite the fact it will be displaying information from the model for the user to see and interact with. The controller acts as intermediary between models and views.
In Apple's words, "A controller object interprets user actions made in view objects and communicates new or changed data to the model layer. When model objects change, a controller object communicates that new model data to the view objects so that they can display it."
From Jeff Atwood's Excellent blog "Coding Horrors":
Like everything else in software
engineering, it seems, the concept of
Model-View-Controller was originally
invented by Smalltalk programmers.
More specifically, it was invented by
one Smalltalk programmer, Trygve
Reenskaug. Trygve maintains a page
that explains the history of MVC in
his own words. He arrives at these
definitions in a paper he published on
December 10th, 1979:
Models Models represent knowledge. A
model could be a single object (rather
uninteresting), or it could be some
structure of objects.
There should be a one-to-one
correspondence between the model and
its parts on the one hand, and the
represented world as perceived by the
owner of the model on the other hand.
Views A view is a (visual)
representation of its model. It would
ordinarily highlight certain
attributes of the model and suppress
others. It is thus acting as a
presentation filter.
A view is attached to its model (or
model part) and gets the data
necessary for the presentation from
the model by asking questions. It may
also update the model by sending
appropriate messages. All these
questions and messages have to be in
the terminology of the model, the view
will therefore have to know the
semantics of the attributes of the
model it represents.
Controllers A controller is the link
between a user and the system. It
provides the user with input by
arranging for relevant views to
present themselves in appropriate
places on the screen. It provides
means for user output by presenting
the user with menus or other means of
giving commands and data. The
controller receives such user output,
translates it into the appropriate
messages and pass these messages on to
one or more of the views.
The best way to understand this (like many core concepts of iOS programming cough HIG cough), is to read Apple's documentation and try it. Here is a good design pattern overview (including MVC) for beginners, including a tutorial: Link
I have finally decided to hop up on the train of MVC 2.
Now I have been doing a lot of reading lately and following is the architecture which I think will be good enough for most Business Web Applications.
Layered Architecture:-
Model (layer which communicates with Database). EF4
Repository (Layer which communicates with Model and includes all the queries)
Business Layer (Validations, Helper Functions, Calls to repository)
Controllers (Controls the flow of the application and is responsible for providing data to the view from the Business Layer.)
Views (UI)
Now I have decided to create a separate project for each layer (Just to respect the separation of concerns dilemma. Although I know it's not necessary but I think it makes the project look more professional :-)
I am using AutoMetaData t4 template for Validation. I also came across FluentValidation but cant find much on it. Which one should I go with?
Which View Engine to go for?
Razor View Engine Was Love at first sight. But it's still in beta and I think it won't be easy to find examples of it. Am I right?
Spark .. I can't find much on it either and don't want to get stuck somewhere in the middle crying for help when there is no one to listen...:-(
T4 templates auto generate views and I can customize them to generate the views the way I want? Will this be possible with razor and spark or do I have to create them manually?
Is there any way to Auto generate the repositories?
I would really appreciate it if I can see a project based on the architecture above.
Kindly to let me know if it's a good architecture to follow.
I have some confusion on the business layer like is it really necessary?
This is a very broad question. I decided to use Fluent NHibernate's autoconfig feature for a greenfield application, and was quite impressed. A lot of my colleagues use CakePHP, and it needed very little configuration to get it to generate a database schema compatible with the default conventions cake uses, which is great for us.
I highly suggest the book ASP.NET MVC2 in Action. This book does a good job at covering the ecosystem of libraries that are used in making a maintainable ASP.NET MVC application.
As for the choice of view engines, that can depend on your background. I personally prefer my view to look as much like the HTML as possible, so I would choose Spark. On the other hand if you are used to working with ASP.NET classic, the WebForms view engine may get you up and running fastest.
Kindly to let me know if its a good architecture to follow?
It's a fine start - the only thing I would suggest you add is a layer of abstraction between your Business Logic and Data Access (i.e: Dependency Inversion / Injection) - see this: An Introduction to Dependency Inversion.
i know its not necessary but i think it makes the project looks more professional :-)
Ha! Usually you'll find that a lot of "stuff" isn't necessary - right up until the moment when it is, at which point it's usually too late.
Re View Engines: I'm still a newbie to ASP.NET MVC myself and so aren't familiar with the view engines your talking about; if I were you I'd dream up some test scenarios and then try tackling them with each product so you can directly compare them. Often, you need to take things for a test drive to be more comfortable - although this might take time, but it's usually worth it.
Edit:
If i suggest this layer to my PM and give him the above two reasons then i don't think he will accept it
Firstly, PM's are not tech leads (usually); you have responsibility for the design of the solution - not the PM. This isn't uncommon, in my experience most of the time the PM isn't even aware they are encroaching on your turf that isn't theres. It's not that I'm a "political land grabber" but I just tend to think of "separation of concerns" and, well, I'm sure you understand.
As the designer / architect it's up to you to interpret requirements and (taking business priorities into account) come up with solution that provides the best 'platform' going forward.
(Regarding DI) My question is , is it really worth it?
If you put a gun to my head I would say yes, however the real world is a little more complex.
If you answer yes to any of these questions then its more likely using DI would be a good idea:
The system is non-trivial
The expected life of the system is more than (not sure what the right figure is here, there probably isn't one, so I'm going to put a stake in the ground at) 2 years.
The system and/or its requirements are fluid.
Splitting up the work (BL / DAL) into different teams would be advantageous to the project (perhaps you're part of a distributed team).
The system is intended for a market with a diverse technical landscape (e.g: not everyone will want to use MS SQL).
You want to perform quality testing (this would make it easier).
The system is large / complex, so splitting up functionality and putting it into other systems is a possibility.
You want to offer more than one way to store data (say a file based repository for free, and a database driven repository for a fee).
Business drivers / environment are volatile - what if they came to you and said "this is excellent but now we want to offer a cloud-based version, can you put it on Azure?"
Id also like to point out that whilst there's definitely a learning curve involved it's not that huge, and once you're up-to-speed you'll still be at least as fast as you are now; or at worst you;ll take a little longer but you'll be providing much more value (with relatively less effort).
In terms of how much effort is involved...
One-Off Tasks (beyond getting the team up to speed):
Writting a Provider Loader or picking DI Framework. Once you've done this it will be reusable in all your projects.
'New' Common Tasks (assuming you're following the approach taken in the article):
Defining interface (on paper) - this is something you'll be doing right now anyway, except that you might not realise it. Basically it's OO Design, but as it's going to be the formal interface between two or more packages you need to give it some thought (and yes you can still refactor it - but ideally the interface should be "stable" and not change a lot; if it does change it's better to 'add' than to 'remove or change' existing members).
Writting interface code. This is very fast (minutes not hours), as you're not writting any implementation; and when you go to implement you can use tools provided by your IDE to generate code-stubs based on the interface.
Things you do now that you'd do differently:
Instantiating a variable (in your BL classes) to hold the provider, probably via a factory. Writting this shouldn't take long (again, minutes not hours) and it's fairly simple code to copy, paste & refactor where required.
Writing the DAL code: should be the same as before.
Sometimes it is way more easy to learn patterns from code : Sharp Architecture is a concrete implementation of good practices in MVC, using DDD.