OOAD - Properties representing relationships between two types - relationship

I have started to model some city-transport data (bus lines and bus stops) for a community project. The data arrived to me as JSON files, and I'd like to create some classes from it, considering the already available data at first.
There is a BusLine object, whose JSONs don't contain information about which BusStop are related to it.
And there is a large collection of BusStop, of which one property is BusLines, a collection of (references to) bus lines which pass about that stop.
So far I have modelled this (C# style, but intended just for visualization at first):
public class BusLine
{
public String code;
public String name;
public List<DirectPosition> route;
}
public class BusStop
{
public String code;
public DirectPosition location;
public List<BusLine> busLines;
}
My doubt, from now, is this: most probably, I'll want to know the BusStops associated with a given BusLine. I imagine some possible ways of doing it, but am not sure at all how this rather trivial situation should be addressed. My naive thoughts:
Create a getStops() method that would look somewhere to check which stops existed along that route, and create such list on-the-fly;
Create an explicit List<BusStop> stops property in BusLine class (that sounds very wrong);
Eliminate containment altogether and create a third, "Relation" kind of class that would manage (somehow) the relations between those classes. That would mean the knowledge about those relations, extracted from the JSON files, wouldn't be stored "inside" the entities, but somewhere else.
I am pretty sure this is a common pattern (I'd bet there's at least one design pattern for that), but my current level of knowledge gives me no clue...
Thanks for any help!

Related

Single User Application File/Data Storage Recommendations

I currently have a C# winform application in which you enter data that is ultimately relational. The amount of data being stored isn't huge. The original version used SQL CE to store the information. However, I found it to be quite slow. Also, I wanted to be able to save application files using my own extension.
I had changed my approach to basically keep my data loaded in-memory using class objects. To save, I simply serialize everything using ProtoBuf and deserialize when opening a file. This approach is lightning fast and changes are never persisted until a user clicks save. However, I find it a little cumbersome to query my hierarchical data. I query data using Linq-To-Objects. I'll have ClassA having a GUID key. I can reference ClassA in ClassB via the GUID. However, I can't really do an easy SQL join-type query to get ClassB properties along with ClassA properties. I get around it by creating a navigation property on ClassB to ClassA that simple returns ClassA via a LINQ query on the GUID. However, this results in a lot of collection scanning.
What options are out there that give me fast, single-user, relational file storage? I would still like to work in-memory where changes aren't persisted until a user uses File|Save. I would also like to be able to continue querying the data using LINQ. I'm looking at SQLite as an option. Are there better options or approaches out there for me?
UPDATE
I was unaware of the AsReference option in the ProtoMember attribute [ProtoMember(5, AsReference = true)]. If I abandon foreign keys in my classes and simply reference the related objects, then it looks like I'm able to serialize and deserialize using ProtoBuf while keeping my object references. Thus, I can easily use Linq-To-Objects to query my objects. I need to stop thinking from the database side of things.
If you have all your objects in some sort of hierarchical structure, you can also store the exact same objects in other structures at an overhead of 4 bytes/object (32bit machines).
Assuming you have a base object like:
public class HierarchyElement
{
public List<HierarchyElement> Children { get; set; }
public HierarchyElement Parent { get; set; }
}
So you have the root element in a local variable, which via the Children property, and the Children property of those first children, etc etc store an unknown number of objects in a hierarchy.
However, while you are building that object, or after deserialising it, you can add a reference to each HierarchyElement to a List (or other flat structure of your choice).
You can then use this flat list to do your Linq queries against.

MVVM: Handling logical child objects of models in collections

Using MVVM, one type of ViewModels include the Model they represnt as a Field.
So I do have a CompanyModel and a CompanyViewModel that has one instance of CompanyModel.
This CompanyModel has a collection of Divisions belonging to it. So CompanyModel has a List (or some collection class).
Now the CompanyViewModel would want to represent these Divisions as an ObservableCollection<DivisionViewModel>; and you you could add new Divisions in the CompanyViewModel.
What is the best way ensure that the ObservableCollection and the Models collection stay in sync? So when I add a new DivisionViewModel and save it, it automatically saves its model to the CompanyModel's List<Division>?
I have more classes like this Parent/child relations so I would love something I could reuse or implement perhaps in a AbstractViewModel class.
Note: My ViewModels implement IEditableObject
Probably the easiest way to do this is to create a new class that inherits from ObservableCollection, and which takes a source list and various initialization and mapping functions as parameters. Its signature might look something like this:
public class SynchronizedObservableCollection<TDest, TSource> : ObservableCollection
{
public SynchronizedObservableCollection(
IList<TSource> source,
Func<TSource, TDest> newDestFunc,
Func<TDest, TSource> newSourceFunc),
Func<TSource, TDest, bool> mapSourceToDestFunc
{
// Initialize the class here.
}
}
You'd then want handle the CollectionChanged event, creating new Source instances when a new Destination instance got added, deleting existing Source instances when an existing Destination instance got deleted, that sort of thing. You'd use the "new" functions above to create new instances of the various entities, and you'd use the "map" functions above in various Linq queries that would allow you to figure out, say, which instance of a viewmodel your ObservableCollection mapped to a model in your List.
You would use it in your example above like so, perhaps:
var divisionViewModels = new SynchronizedObservableCollection(
company.DivisionList,
division => new DivisionViewModel(division),
divisionVm => divisionVm.Model,
(division, divisionVm) => divisionVm.Model == division);
The exact implementation is left as an exercise to the reader :-). But I've used classes like this with some success in previous projects. Just make sure you work up some good unit tests around it, so that you know you can rely on it, and don't have to spend a lot of time hunting through event-handling callstacks.

Field Name Best Practices (Shadowing or Compund Names)

As the red block above (warning that this is a subjective question and may be closed) there may not be a stone etched law on this, but I don't see why that would warrant closing a question.
...Rant aside
I am planning on implementing Hibernate as my persistence framework, which may fix my problem upon implementation, but I have DB tables that translate into class and sub-class (many specifics and complications that exist in real life are omitted :) ):
//dbo.a with column Name
class a {
public String Name;
}
//dbo.b with column Name and a foreign key to dbo.a
class b extends a {
public String Name;
}
So, for the what should be done and why:
Shadowing:
I could leave these as is, which would require some reflection cleverness (per http://forums.sun.com/thread.jspa?threadID=5419973 ), when working with objects whose types are unknown at compile.
Compound Names:
I could name all of my fields preceded by its class's name i.e. a.aName and b.bName, which gets really ugly in real life: Door.DoorName and RotatingDoor.RotatingDoorName
Getters and Setters:
I didn't mention this one, since with JavaBeans these will be derived from the field names, and I believe Hibernate uses annotated POJOs.
To influence the results a little, shadowing seems to be the most robust, at least in my case where class a extends an abstract class with Name defined, then b shadows with its own Name when applicable. Using compound names would mean that if I wanted to add a NickName column to all my DB tables then I would have to add that field to each type (and then what's the point of inheritance?!)
In the end I decided to find out what people, hopefully who have experienced pros/cons of an implementation of one or more of these technique, have to say on the issue; or that convenient stone etched best practice will do :)
-Nomad311
you should only define your member in the base class if you need it in all subclasses. hibernate offers various types of mappings for class trees. take a look at Inheritance mapping in the manual to get a feeling of it.
you can define your mapping either via an xml file or via annotations.

Model-View-ViewModel pattern violation of DRY?

I read this article today http://dotnetslackers.com/articles/silverlight/Silverlight-3-and-the-Data-Form-Control-part-I.aspx about the use of the MVVM pattern within a silverlight app where you have your domain entities and view spesific entities which basically is a subset of the real entity objects. Isn't this a clear violation of the DRY principle? and if so how can you deal with it in a nice way?
Personally, I don't like what Dino's doing there and I wouldn't approach the problem the same way. I usually think of a VM as a filtered, grouped and sorted collections of Model classes. A VM to me is a direct mapping to the View, so I might create a NewOrderViewModel class that has multiple CollectionViews used by the View (maybe one CV for Customers and another CV for Products, probably both filtered). Creating an entirely new VM class for every class in the Model does violate DRY in my opinion. I would rather use derivation or partial classes to augment the Model where necessary, adding in View specific (often calculated) properties. IMO .NET RIA Services is an excellent implementation of combining M and VM data with the added bonus that it's usable in on both the client and the server. Dino's a brilliant guy, but way to call him out on this one.
DRY is a principle, not a hard rule. You are a human and can differentiate.
E.g. If DRY really was a hard rule you would never assign the same value to two different variables. I guess in any non trivial program you would have more than one variable containing the value 0.
Generally speaking: DRY does usually not apply to data. Those view specific entities would probably only be data transfer objects without any noteworthy logic. Data may be duplicated for all kinds of reasons.
I think the answer really depends on what you feel should be in the ViewModel. For me the ViewModel represents the model of the screen currently being displayed.
So for something like a ViewCategoryViewModel, I don't have a duplication of the fields in Category. I expose a Category object as a property on the ViewModel (under say "SelectedCategory"), any other data the view needs to display and the Commands that screen can take.
There will always be some similarity between the domain model and the view model, but it all comes down to how you choose to create the ViewModel.
It's the same as with Data Transfer Objects (DTO).
The domain for those two object types is different, so it's not a violation of DRY.
Consider the following example:
class Customer
{
public int Age
}
And a corsponding view model:
class CustomerViewModel
{
public string Age;
// WPF validation code is going to be a bit more complicated:
public bool IsValid()
{
return string.IsNullOrEmpty(Age) == false;
}
}
Differnt domains - differnet property types - different objects.

Best Practices for Images in a Model with Castle ActiveRecord/MonoRail

Our "user" model needs a small profile picture on it, and I'm not entirely sure how to handle it. Of course we could just save it to a folder on disk and store the path/filename to the database, but I think I'd rather have it stored in the DB itself.
My first thought was to have a property on the model like this:
[Property]
public byte[] ProfilePicture
{
get;
set;
}
But it sure feels like I'm going to have to go a LONG way to get it working this way -- getting a byte array from the database, then converting it to an image with some sort of handler.
Has anyone seen a good tutorial on how to handle this sort of thing? It seems like it would be a common enough requirement that I'd find something MonoRail specific, but so far my searches have come up empty.
About storing images on database or files, see this question.
If you decided to store it on DB, the most important thing is that you don't retrieve the byte[] every time you query for a User, that could be potentially a lot of data and a perf problem. To do that you could either store the image in another table or map the byte[] to another entity with the same table (assuming the user can have only one picture):
[ActiveRecord("users")]
public class UserWithoutPicture {
[PrimaryKey]
public virtual int Id {get;set;}
...
[BelongsTo]
public virtual UserProfilePicture ProfilePicture {get;set;}
}
[ActiveRecord("users")]
public class UserProfilePicture {
[PrimaryKey]
public virtual int Id {get;set;}
[Property]
public virtual byte[] Image {get;set;}
}
This would have some funky behaviors though. For example, for any given user, the ProfilePicture would never be null. You wouldn't really insert or delete UserProfilePicture since it's actually the user, instead you would always update. And you would incur an additional join, and you have to be aware of SELECT N+1. That's just off the top of my head, completely untested.
Conclusion: storing images in another table is much more flexible.
If you want the convenience of dealing with an Image instead of raw byte[], implement IUserType. But remember that Image is an IDisposable, and it'll be very hard to dispose it at the right time.
Implementing a Monorail controller that returns an image is quite straightforward... just use [ARFetch] to get the UserProfilePicture by id and write to the Response stream with the appropriate content-type.

Resources