Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm beging to work on a re-design (software design) of XAML-based application, I wrote 2 months ago. I think I made lot's of architectural mistakes during development, which led to situation when the UI part of app is hard to extend, maintain, code is hard to understand. My app is written using PRISM 4 in MVVM style, but despite the fact that Prism was invented for modular design my App turned out to be very monolithic. I'm going to continue to use PRISM 4 in new design, but this time I want to break my UI part of application in smaller, reusable, extendable building blocks.
Suppose we are designing data input form.Top container contains Save,Cancel buttons and TabControl, which contains 2-3 tabs that contain lot's of grouped input controls.
The are 2 completly different aproaches to UI design I can see: static (compile-time), dynamic(run-time). Static it's when you predefine your UI before compiling, i.e DataGrid with columns defined in XAML. Dynamic it's when you compose UI at runtime, i.e you defined DataGrid in XAML but add columns at runtime based on user asctions.
What rules you use when you decide which aproach to use, sattic or dynamic? What you would choose in this particular example?
Next big question is how to break UI to pieces.
What rules you use when you define UserControls, how you would define UserControls for this example form? Now about ViewModels, would you create single VM for this example form or multiple (explain)? What do you think about situations when ViewModel contains other ViewModels (not simple wrapers around model, but real VM which contains logic).
And now the hardest question at least for me. Extending UI building blocks (UserControls and ViewModels).
Situation when you need to create a copy of some Form but with slightly different interface and|or logic is quite often, especially when you need to integrate authorization (permissions) in UI. Suppose we need to support slighly different version of out example form (doesn't matter how many exactly versions, suppose 2-6).
I can think of these aproaches to solve this problem:
Create duplicates of whole from (usercontrols and viewModels) and modify them (the static way). The good thing all variants are independent, great flexibility, no dependecies, the bad thing code duplicate, if you will need to change something in all variants most likely you will have to modify this everywhere, especially with ViewModels.
Conditional presentartion, you add lot's of conditional code to your ViewModel, like IsThisVisible, IsThatDisabled (the dynamic way). The good thing maximum code reuse, the bad thing code bloat and mess. Your code will be hard to understand,maintain.
Break UI to very small atomic UserControls, compose separate form variants from this UI pieces, and use ViewModel inheritance with virtual members and overrides. I haven't ever used inheritance of ViewModels, and would like to hear your opinion on this subject.
n. Other aproaches I can't think of.
In my experience, the development path tends to work this way:
Design a view in Blend or Kaxaml or whatever, and a view model that backs the view.
Realize that portions of the view need to be dynamic. Implement flags in the view model and styles in the view to show/hide them.
Realize that all the flags are getting out of hand. Get rid of the flags, and refactor the view to present collections of user controls, and the view model to dynamically populate collections of view models.
It sometimes happens that I know well in advance that I'm going to need to use approach #3, and I design for it from the start.
But one of the beauties of WPF and MVVM is that even if I don't design for this from the start, it's not too hard to move in that direction if circumstances demand it. Refactoring a bunch of view model properties into a single collection of view models doesn't take a whole lot of time or effort once you've done it a few times.
I can tell you this, though: making a copy of a XAML object and editing it makes klaxons sound in my head. It's possible to imagine circumstances under which that might be OK, but it's not the way to bet.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Currently I'm redesigning an existing program which uses a master table which contains multiple values. (C# .net core 3.0 & EF) (One big lookup table)
Much of these values are rarely changing and I would put them in a c# enum.
Some examples: Language, Sex, ReceiptStatus, RiskType, RelationType, SignatureStatus, CommunicationType, PartKind, LegalStatute, ...
The list goes on and on and currently has 143 different categories, each having their own values with 2 translations in it.
My company wants the values to be in the database, so a non programmer can change them when they have to.
However it doesn't feel good at all. I would love to separate the table but creating 143 tables seem a bit of an overkill. If it was only 5-10 lookup tables it would have been fine..
Any advice? Stick to 1 lookup table? Feels wrong to my eyes. Multiple tables?
Convince my company we should just use C# enums which work perfectly fine, ruling out the possibility that a non programmer can edit them?
Based on your inclination to use enums, I'm going to assume that these lookup values do not change often.
Buckle up because a lot of hard-fought knowledge about maintainability is embedded in the analysis below. Let me break down the approaches you are considering:
Pure enums: This is the least flexible approach because it closes a lot of doors. As you said, changing values requires a developer and a deployment. What's your strategy if you eventually have other tables that need to relate to one of your many, many values? To me this is far too restrictive, especially since with either of the other approaches, you could create a .t4 template that generates
enums based on the data. Then if the data changes, you just
re-generate. I do this a lot.
One giant lookup table: Not as flexible as it may seem! This trades complexity, single responsibility principal, and referential integrity against repetition/table spam and is probably an expression of the Big Ball of Mud anti-pattern. You could add a column to this table that controls where a given value can be used, and that will allow you to have sane drop down lists, but that isn't as good as referential integrity. If other tables need to relate to a lookup, you have to relate against this entire table, which is much less clear. You will have to be careful to enforce your own layer of referential integrity since the database can't help you. Finally, and this is a big deal, if any if your 143 values has or will ever have extra complexity and could really benefit from an additional column, cognitive load begins to escalate. If five of the 143 need their own columns, you now have to hold all five columns in your mind to understand any one column... That is agony. Here's a thought experiment for you if I'm not getting my point across: why not build your entire project as one giant table?
143 tables: The most flexible approach, and all things considered, the easiest to maintain by a massive margin. It does not close any doors; down the road you can still create a UI for editing any value you want. If you want to relate other tables to a lookup value, that relationship will be easy to understand because you can relate to LegalStatus instead of GiantEverythingTable, and enjoy the benefits of referential integrity, never having to worry about corrupting your own data. You can also script table and index creation with something like NimbleText (a great tool and a hidden gem). There will be a huge number of tables, which is itself a minor maintenance problem, but it's one that doesn't actually break anything and doesn't lead to cognitive load. This is an acceptable trade-off. I would go this way and generate enums using t4.
The thing about most software projects of any size is that you may look at my objections and say they don't apply, and you might be right. But if this thing is going to be in active development, you have to ask: are you sure? Do you really know what's going to happen in a year?
When considering trade-offs, I've learned to assign a lot of weight to the most flexible/simple decision. Maintainability problems are what kill software projects. They are the enemy.
Hope that helps!
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have extensive WinForms experience, but am new to WPF. Implementing Form design vision through XAML was easy enouhg to delve into, but I'm still a little unclear on what is expected from the M-V-VM programming style. I understand the principle of separating how things look from how they behave, but doing so sensibly in some cases continues to elude me.
For example, if I have a keypad with 9 buttons, and I want a means of enabling/disabling all of them through their IsEnable property, the Form designer in me wants to address them all in a code-behind method targeting them by Design Name. What is the WPF equivalent of such an operation? Am I expected to manage a series of bools in codebehind, and bind each one in the XAML to each respective button attribute? Thanks for any guidance. If this one scenario is explained, it should be sufficient to point me in the right direction
That specific problem is easily solved with binding. You would bind your buttons IsEnabled property to a public Property in your ViewModel and based on the logic contained in your ViewModel when that property value is changed your keypad button would get enabled or disabled.
As #GCamel mentioned you could also have a POCO class that would represent your button which would implement INotifyPropertyChanged interface with one of the properties being the IsEnabled property. You would add instances of this class to an ObservableCollection and when that IsEnabled property changes your button would become enabled or disabled in the UI.
I would also strongly recommend using one of the MVVM frameworks, my personal favorite is Simple MVVM Toolkit by Tony Sneed who also has a great article about the dialogs problem mentioned by #cwap Climb Onboard on the MVVM Message Bus
ideally, you would have an observable collection of button_info with IsEnabled property, icon and text - bind the collection to whathever suitable control like itemsControl, list, or grid and associate your button_info to a datatemple...you see what i mean ? no gui, no gui, just viewmodel and binding
or like this sample ???
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I got this asked in an interview recently . He wanted to know the order of instantiation of Model View and ViewModel what the precise order of instantiation would be ?
I thought the view is always instantiated first and then comes the viewmodel and then comes the model. was i wrong ??
I thought the view is always instantiated first and then comes the viewmodel and then comes the model. was i wrong ??
There is no single standard. There are, in general, two approaches:
View-First - The View will be instantiated first, and in turn instantiate the ViewModel, which will likely create the underlying model. This typically means the order of instantiation is View->ViewModel->Model.
ViewModel-First - The ViewModel is created, which in turn instantiates the Model. The View is generated by the system based on DataTemplates after the ViewModel. This would mean the order of instantiation would be ViewModel->Model, then View (indirectly from XAML).
Most frameworks which are geared heavily towards a designer-first approach tend to do View-First construction. This makes it easier to work with the designer (in general).
Many frameworks which are geared heavily towards developer-focused scenarios will often do ViewModel first. This approach can actually lead to even less coupling, and simpler "code-only" construction of everything from the ViewModel level.
This is an open ended question because you can look at it conceptually, in which case it follows the acronym. If you look at it in practice (particularly referring to WPF or WinStore Apps) its a bit different.
Conceptually
Model should be instantiated first because all ensuing decisions of the application will be based on the model on which the app was designed to operate on. Then the view model, because views depend on view models, not the other way around. One VM can have multiple views, but one view generally does not have multiple view models (generally!). Then the view(s) that present the data.
Practice (In WPF and WinStore Apps)
The App class is instantiated first, which fits in some odd portion of the VM-M area. But that's not completely relevant because it's outside the scope of the pattern. The View is usually created and attached to the visual tree first. Then the ViewModel is instantiated in the code-behind, at which point the model is loaded. Then a massive UI refresh occurs that displays everything that was loaded initially. From then on out, everything in the 'conceptually' portion holds true.
This question may get closed due to opinions, as there is no definite answer. but this is what I've seen, read, and experienced.
Well that's a strange interview question. In my opinion and in general, I would agree with you. The view model would instantiate the model and the view would come first, instantiating the view model. But of course, it very much depends on the architecture of the application. The beauty of WPF enables these things to be done in different ways. Then you also have dependency injection, so I would say that the answer should really be 'it depends'.
The question is a bit silly, because it's limited to a simple scenario where each layer is a single class. Suppose one view model provides another one. If we decide "view comes first", do we need to create another view before we are allowed to call that function on the original view model? What if the view must be chosen based on the returned view model? And on the flip side, if we decide "viewmodel comes first", what if the new viewmodel must be chosen based on parameters input from the view?
A layered architecture is about dependencies. MVVM says V depends on VM and VM depends M. It doesn't say anything about instantiation order. You might decide that dependencies should be passed into constructors, meaning that instantiation order needs to be M-VM-V, but I don't see any practical reason to try to enforce such a small detail throughout an entire application
IMHO it is a Trojan horse question to see how one thinks more than an actual answer to see if one can quantify their experience with actual MVVM projects.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I have an application that requires the use of a lot of different enumerations. The application can be devided into various layers. For the sake of the example let's assume three layers: a 3rd party analytics library, the application business logic and the UI/presentation logic.
In many cases all layers may have the need for an enum representing the same concept. Let's take a payment frequency for instance. (e.g. annual, semi-annual, quarterly etc...).
The 3rd party library provides its own enum, the various classes in the business logic layer would need a similar enum, and finally the UI layer may need it for presenting various choices in dropdowns etc...
Now, normally I'd like to shield the user of each layer from its internal dependencies and implementation details by not exposing types from internal dependcies in the public interfaces of the layer. That means that even though the interaction with the 3rd party lib requires the use of its own "Frequency" enum, I'd need to create an equivalent "Frequency" enum for the business layer and potencially another one for the UI layer...
All of this requires a lot of mapping back and forth, with potencially lot of additional mapper classes. The adventage on the other hand is that each layer may decide to exclude values it does not need or support from its own version of the enum...
Now since I have to deal with a lot of enums, I was just wondering if this is generally a good thing to do, or am I just overcomplicating things?
I would say you're overcomplicating things. Why not have a separate project for shared entities like this? You can then have each assembly reference your Common project to reference the necessary enums and still have them all totally independent of each other.
Well, i may be missunderstanding you but, actualy, you will just need, in data layer, which is viewd by the logic layer, your enuns. Using your own example, you would have a column names PaymentFrequency in a table. Your table should be mapped in your data layer for this specific field, so you'll create a enum and the type of the column PaymentFrequency - by this moment an attribute of your table class or entity - will be setted as the enum created for this purpose. So, when you point your logic layer to request/access your data layer, you'll need to understand this same enum - so, if your using a DAL layer between logic and data layers, i recommend you to create the enuns in a separate class/file. Well, in your logic layer - by using the enum options - you'll populate a simple Combo component with the enum options, so, you'll be presening the options in the UI by hiding all your layers, in a way that users won't know you are actually using a enum to handle the options.
I hope this help. Sorry - really sorry - for this * bad english!
If this don't help, post some cod examples to be easier to help you =)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Before down-voting let me explain my question. I have a little experience in designing architectures and try to progress. Ones, when I was fixing a bug, I came up with a conclusion that we need to make our private method to be public and than use it. That was the fastest way to make my job done, and have a bug fixed. I went to my team-leader and said it. After I've got a grimace from him, I was explained that every public method is a very expensive pleasure. I was told that every public method should be supported throughout the lifetime of a project. And much more..
I was wondering. Indeed! Why it wasn't so clearly when I was looking in the code. It wasn't also so evidently when I designed my own architectures. I remember my thoughts about it:
Ahh, I will leave this method public, who knows, maybe it will come usefull when the system grows.
I was confused, and thought that I made scaleable systems, but in fact got tons of garbage in my interfaces.
My question:
How can you explain to yourself if a method is really important and worthy to be public? Are any counterexamples for checking it? How you get trained to make private/public choise without spending hours in astral?
I suggest you read up on YAGNI http://c2.com/cgi/wiki?YouArentGonnaNeedIt
You should write code to suit actual requirements because writing code to suit imagined requirements leads to bloated code which is harder to maintain.
My favourite quote
Perfection is achieved, not when there is nothing more to add, but
when there is nothing left to take away.
-- Antoine de Saint-Exupery French writer (1900 - 1944)
This question need a deep and thorough discussion on OOP design, but my simple answer is anything with public visibility can be used by other classes. Hence if you're not building method for others to use, do not make it public.
One pitfall of unecessarily making private method public is when other classes did use it, it makes it harder for you to refactor / change the method, you have to maintain the downstream (think if this happen to hundreds of classes)
But nevertheless maybe this discussion will never end. You should spend more time reading OOP design pattern books, it will give you heaps more idea
There are a few questions you can ask yourself about the domain in which the object exists:
Does this member (method, property, etc.) need to be accessed by other objects?
Do other objects have any business accessing this member?
Encapsulation is often referred to as "data hiding" or "hiding members" which I believe leads to a lot of confusion. Inexperienced developers would rightfully ask, "Why would I want to hide anything from the rest of my code? If it's there, I should be able to use it. It's my code after all."
And while I'm not really convinced with the way in which your team leader worded his response, he has a very good point. When you have too many connection points between your objects, you end up with too many connections. Objects become more and more tightly coupled and fuse into one big unsupportable mess.
Clearly and strictly maintaining a separation of concerns throughout the architecture can significantly help prevent this. When you design your objects, think in terms of what their public interfaces would look like. What kind of outwardly-visible attributes and functionality would they have? Anything which wouldn't reasonably be expected as part of that functionality shouldn't be public.
For example, consider an object called a Customer. You would reasonably expect some attributes which describe a Customer, such as:
Name
Address
Phone Number
List of orders processed
etc.
You might also expect some functionality available:
Process Payment
Hold all Orders
etc.
Suppose you also have some technical considerations within that Customer. For example, maybe the methods on the Customer object directly access the database via a class-level connection object. Should that connection object be public? Well, in the real world, a customer doesn't have a database connection associated with it. So, clearly, no it should not be public. It's an internal implementation concern which isn't part of the outwardly-visible interface for a Customer.
This is a pretty obvious example, of course, but illustrates the point. Whenever you expose a public member, you add to the outwardly-visible "contract" of functionality for that object. What if you need to replace that object with another one which satisfies the same contract? In the above example, suppose you wanted to create a version of the system which stores data in XML files instead of a database. If other objects outside of the Customer are using its public database connection, that's a problem. You'd have to change a lot more about the overall design than just the internal implementation of the Customer.
As a general rule it's usually best to prefer the strictest member visibilities first and open them up as needed. Combine that guideline with an approach of thinking of your objects in terms of what real-world entities they represent and what functionality would be visible on those entities and you should be able to determine the correct course of action for any given situation.