strategy pattern or builder pattern? - strategy-pattern

I know the strategy pattern is a behavioral pattern that encapsulate an algorithm in a class. Also that the builder pattern is to separate the construction of a complex object.
Now, I have to create different views of map (seller view, customer view) (each map has: houses, buildings, streets) depending on a type that in be selected in the UI by the user. I want to do this as extensible as possible as maybe some other views will be added to the program. In this case, should I create a strategy which encapsulates the algorithm to create the different views? or should apply the builder pattern? or should I create a strategy with a builder inside?.
public class Map
{
private List<House> Houses { get; set; }
private List<Building> Buildings { get; set; }
private List<Street> Streets { get; set; }
}
In the UI:
Select with: Seller view, Customer view.
Map: shows the map with all his things and depending on the select, depends the view that is shown.
Seller view: houses and building in green are for sale, and in red are sold.
Customer view: house in blue is the selected to buy and only appears houses in sale.
Thanks and wish you understand my problem!

As far as I understood, you have a different behaviour depending on user role. Therefore it is suitable to have different strategies of presenting the data. Using the builder pattern inside of strategies sound reasonable as well when you have to construct a complex obiect.

Related

Best Implementation for using Centralized Data Aggregator and WPF Toolkit Line Series

I have a singleton class DataPacketAggregator that is collecting DataPackets from an embedded device connected via USB. The Packets are always received in a burst. Every DataPacket contains a Sensor Identification and a Source Address (coming from the ZigBee Communication). Basically that is what the DataPacket class provides:
public class DataPacket
{
public String SourceAddress {get; set;}
public Byte SensorID {get; set;}
public DateTime Timestamp {get; set;}
public Int16 Value {get; set;}
}
The Aggregator class provides this Basic Implementation:
public class DataPacketAggregator: INotifyPropertyChanged
{
Dictionary<String, ObservableCollection<DataPacket>> _dpkts; //Container
//Method for getting an observable collection containing only values belonging to
//SourceAddress
public ObservableCollection<DataPacket> GetDataBySource(String Source)
{
ObservableCollection<DataPacket> dpkts;
this._dpkts.TryGetValue(Source, out dpkts);
return dpkts;
}
...
}
So because all values provided to the TableView are already inside an ObservableCollection the UI is notified about any changes going on in the DataPacketAggregator.
I already provide a table view of the data collected but there every sensor is displayed. At the moment I am storing the DataPackets in a Dictionary with Key SourceAdress and a Value of DataPacket-Object which contains the data specific to the DataPacket received.
What I want to do now is to create a one line series chart for each Sensor ID associated with a selected SourceAddress which is selected from a ComboBox on the User Interface. The LineSeries shall display the DataPacket Data for Timestamp on the Independent Axis and the Value on the Dependent Axis. The ItemsSource Property of this ComboBox is bound to the available Keys in the Dictionary providing the data. The point is that not all Sources need to have the same amount of Sensors associated with it and I want to dynamically recreate the LineSeries Objects depending on the Amount of Sensors.
I thought about several implementations that may be possible:
Nest another dictionary inside the already existing dictionary which would gain quick access to the values belonging to a specific sensor. The problem is that you need to "merge" the data again if you want to have access to the full collection of data.
Apply a grouping with a LINQ-Query to get all data associated with a specific sensor. I would prefer this solution but there are two points for me here. First: How to update the UI then without major performance losses (Running all queries again and again)? How to Notify the UI? Because normally I would just want to notify the UI if there is any change in the relevant queries but I can not simply detect that. So I would have to do an update and redraw of the whole UI as soon as any DataPacket (even not relevant for the UI Drawing would be added)
Adding an additional Property inside the DataAggreagtor that may be set to the currently relevant SourceAddress (also through binding). I could return an ObservableCollection that only have the SourceAddress and I can query only on a subset of the whole data. Furthermore it would be possible to update just this observable collection because then it is known which SourceAddress to display and I can update the Collection without requerying. The Major drawback with this is that I would always be restricted to showing data from a single source.
At the Moment I am really unsure what would be the best solution to this problemn and I am also not really familiar with the WPF Toolkit Charting Component.
Finaly I implemented it as a Collection that is triggered by another Property which is bound to the ComboBox. The Update is just triggered when the SourceAddress corresponds to the currently displayed. It finally works like this but the major restriction is of course only having a single Source to be viewable.

MVVM - Viewmodels in Datagrid rows?

i want to write a little programm to manage article.
the pgm should show a list of article in a datagrid.
the can be 500/1000 articles that must be displayed in the grid.
Should i use viewmodels in the datagrid rows like josh smith does in his example here http://msdn.microsoft.com/en-us/magazine/dd419663.aspx ?
i tested a little bit in joshs example.
so i took his customers.xml file and extended it to 800 customers.
-> the app took a little (more)time to start and closing it (if show click the "show all customer" button) will take a few seconds. So it should be a heavy load for the system using viewmodels ?
can someone explain me the advantage using viewmodels as datagrid rows instead of articles?
What is the better way ?
public ObservableCollection<ArticleViewModel> AllArticle { get; private set; }
or
public ObservableCollection<Article> AllArticleraw { get; private set; }
Whether or not to use ViewModels as your DataGrid Rows really depends on how much functionality each row must have.
If the grid is read-only, for display purposes only, and the underlying data will not change, then ViewModels would probably be overkill for a row.
However, if your user may interact with the row, perhaps edit values in a row, or if values in the row may change as a result of an external action, and you want those changes to reflect automatically in the grid, then you should consider ViewModels.
And keep in mind that a ViewModel is just a name for an object that serves a purpose - it can be as heavy or as light as you need it to be. For example, if you want your row to reflect changes in the grid immediately, it can be a simple POCO that has properties for each row column, and then implements INotifyPropertyChanged to notify the grid when one of those property values has changed.
Don't let heavy-weight implementations of ViewModels scare you away from the concepts of MVVM - implement only the features you need in each ViewModel.

Common model among multiple views

New to WPF. I have a Product model that is an L2S entity. I am creating an application in WPF to edit the product information to potentially replace an old Windows forms app I have. the application has a tab control with a number of tabs on it, such as Packaging, Marketing, Photos, Construction, etc.
My question is how do I structure this in a MVVM system. Do I have a separate view for each tab, each with it's own view model relating to it's particular subset of the Product model? Or do I have a single view with the tab control and all of the fields and a single view model to encompass the model in it's entirety? Or am I going about it completely wrong?
I feel like the first option is the way to go, but then I am also unsure of how to share the same model across multiple view models. Can anyone shed some light on this for me?
--Edit--
Examples of data on the pages:
Marketing has several text fields, and a few subset entity collections such as features, applications, and cross references.
Photos handles a collection of Photos for the product
Packaging and Construction are each a large collection of text fields/combos/checkboxes related to their respective information in the Product
With this minimum of info you've provided I would suggest following solution:
Main ProductView view
Separate View for the each tab
Main container ViewModel: ProductViewModel
For complex tabs separate view model as well. For instance you would have a separate PackagingViewModel so ProductViewModel should expose public PackagingViewModel Packaging property
ProductViewModel should accept all model-related stuff (perhaps some services, model entity, etc) and then initialize all other child view models.

Treeview inheritance relationship

Hallo,
I am trying to visualize a hierarchial (Is-a) class relationship using Treeview with WPF but I find it difficult.
I studied some code from the Internet like
http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx
These examples show a (has-a) class relationship and in this case the visualization with WPF+Treeview+Databinding is quite clean and intuitive.
On the contrary What I have is
public class Device() { }
public class VisionDevice() : Device { }
public class CommunicationDevice() : Device { }
public class SerialComm() : CommunicationDevice {}
public class Webcam : VisionDevice { }
I would like to visualize a WPF treeview structure like that
Device
VisionDevice
WebCam
CommunicationDevice
SerialComm
It is possible to do that using HierarchicalDataTemplate but the solution I found is not very elegant.
In conclusion: Treeviews is good for has-a class relationship but difficult to adapt to is-a relationship. Do you agree?
In conclusion: Treeviews is good for
has-a class relationship but difficult
to adapt to is-a relationship. Do you
agree?
Yes, tree views are good for structures where you know the root and have a connection from that to all its children (e.g. an object knows its properties and those properties are in turn objects which behave the same way), for types it is quite problematic since the traveral is the other way around, the supertype knows nothing of its subtypes but the subtypes know their supertypes (unlike objects which rarely have a reference to their parent).
To visualize types you would first need to collect all the leaves and while going towards the root check which types have a branch in common till you arrive at your target supertype. Not very elegant...
(Alternatively you can start at the root and query all types every time to see if their immediate parent is the type you are currently looking at, in terms of performance that should be even worse)

OOP vs case statement in Windows forms application

I have a software design question. Say I have a Windows form with some elements and I have a customer object. A customer can either be business, private or corporate for example.
Now, all the decisions of what is going to happen in the form will depend on the customer type. For instance, certain elements will be hidden, certain label text will be different, etc...events will respond differently.
Obviously, one way to code this will be to use CASE statement each time the decision needs to be made. Another way would be to have a Customer class and 3 other classed such as BusinessCustomer, PrivateCustomer and CorporateCustomer inherit from the base class. In the latter, a question then arises: how are you going to incorporate a windows from into it....
Edited
I had an idea: can I embed forms within forms? My reqs don't dictate two windows being shown at once, so I don't have to use MDI. But to simplify my design based on some ppl's comments here, I would like to maintain 3 different customer forms, and embed inside the main form on the fly. That way three GUIs are separated and I won't have to deal with every control's visibility.
I am assuming I can just add a form to another form, such as this:
Form child_form = new Form();
parent_form.Controls.Add(child_form);
Those decisions really shouldn't be made in the GUI. You should have a ViewModel behind your GUI that makes those decisions, and that you write unit tests for. (Or a Presenter, or a Controller -- different names that all mean roughly the same thing: get the decisions out of the GUI class and into something you can unit test.)
Then your ViewModel would have e.g. a Boolean property for each element that the GUI would disable, and a method for each action you could take (CloseCustomerAccount() or whatever).
As long as the Form is created for a particular type of customer, and the customer won't change to a different type of customer during the lifetime of the form, you could just pass your Customer object (that stores all of the actual customer data) to the ViewModel's constructor, and then pass your ViewModel to your Form's constructor. The form could set all its Enabled properties right after it calls InitializeComponent(). On the other hand, if the customer type could change, then your ViewModel needs to expose some events for the Form to hook, so the form knows when to re-run its Enabling logic.
Your question then moves out of the Form and into the ViewModel. Do you have one ViewModel class with a bunch of case statements, or three ViewModel classes (maybe with a fourth that's a base class) that use polymorphism, and a factory method somewhere that decides, based on the particular customer, which ViewModel class to instantiate?
I'd let your code be the guide there. Start with the simplest approach, which is probably case statements. Write a unit test for every behavior you care about. If the case statements start to get too awkward, then add a ViewModel descendant for each customer type, and start extracting the case statements into virtual methods. Your tests will catch you if you make a mistake during the refactor.
If you do have 3 different windows, each handling a specific type of customer than there won't be much point in working with the base class or a contract. You could be smart though with a factory class that takes a customer class and determines the correct screen to use.
I've run into this quite a bit. I end up with a base window that handles the generic stuff and then extend it for each concrete type.
I agree with Joshua Belden's answer. Three separate forms for different kinds of customers would likely be the easiest to maintain.
Also, in case you didn't know already, you can derive from a Form class and tweak it in a derived Form class. This is even supported by the designer.
However, I'd like to offer an alternative:
The Bridge Pattern: separate an abstraction from its implementation so the two can vary independently.
What you could do is this:
Create three separate UIImplementation classes. These classes could tweak the UI, and the events for the Customer form. In order to gain access to the private members of the form, you would need to declare the UIImplementation classes as nested within the CustomerForm class. (Use partial classes to separate these into different files). If the form itself is significant, and the tweaks are insignificant, this may be good option. It's difficult to say.
Just go for the three classes implementing some abstract Customer interface. In your app you would have a variable customer of type Customer and an object of a particular Customer type would be stored in there. Your GUI could then just rely on the interface and invoke methods on the customer variable regardless of what customer would be actually interacting with the GUI.
Have a look at this article.
I would go with an MVP type approach and define CustomerPresenter class that exposes a boolean property that will derive your UI controls' enable/disable state via binding.
public class CustomerPresenter
{
private Customer _customer;
public CustomerPresenter(Customer customer)
{
_customer = customer;
}
public bool EnableUI
{
get
{
//TODO: put your customer type basic logic here (switch statement or if/else)
return _customer.Type == CustomerType.Business;
}
}
}
public CustomerForm: WinForm
{
private CustomerPresenter _customerPresenter;
public CustomerForm(){};
public CustomerForm(Customer customer)
{
_customerPresenter = new CustomerPresenter(customer);
}
private void CustomerForm_Load(object sender, EventArgs e)
{
_someButton.DataBindings.Add("Enabled",_customerPresenter,"EnableUI");
}
}
The solution should be driven by data, not your code.
So if you tag various controls as being visible in state "A", "B", or "C", then a single method could look at its state and know which controls to make visible or not.
You know you did it right when adding new controls for state "D" takes no code changes aside from those required to add the controls themselves.
You might also look at breaking the form down into 4 sub-forms, shared, sub-form a, sub-b, then displaying both "Shared" and "Sub-a" together on a parent form ...

Resources