I am learning OOP through developing a C# music management software. So far, I have laid out the interaction of different classes and object as shown on this class diagram http://img811.imageshack.us/img811/7624/classdiagramh.png
I’m however very confused on making my design solid as I am finding a myriad of possibility of how things can be done but I don’t want to end up with a bad design. The main problem I’m having is to make sure that I enforce data integrity between different object (To my understanding, I am supposing that in OOP, like in database design, there is a way one can provide an accuracy, consistency, and reliability of data store in different object as it is done in database design (For example the use of foreign key constraint). For example, in my application, I have Artist, Song, and Album objects that should interact together. I do not want for example to have a song associated with the wrong album by mistake. I have been told that I should do something like:
class Album
{
public String Name{ get; set;}
List<Track> tracks;
public void AddTrack(Track t)
{
tracks.Add(t);
t.Album = this;
}
}
class Track
{
public Album Album{ get; set;}
public String AlbumName
{
get{ return this.Album.Name}
}
public String ArtistName{ get; set}
}
However this is not working for me. Can someone suggest how I can actually make this work. Specifically, how I can add a new song with a title, an album and artist and make sure that If for some strange reason the name of the album is changed, all of the tracks will still return the correct album name, since they're getting the data from the album itself?
Also, can someone suggest a better design. Should I be using inheritance or any polymorphism to make my design robust?
As in DB design you have to make your choices based on your business requirements. Means:
You have to ask yourself questions of possible constellations
- are all the songs on a CD from the same artist? No -> artist field on track, yes -> artist field on album
- do you have to be able to get the album when you know a track, or just all the tracks from a specific album
- ...
What you are doing is correct in the way that you reference from the Track object the name of the referenced Album. What is to mention: they do return the albums name, but just the name the album has in the moment of the GET.
So if you assigned the AlbumName property to a visual control or whatever it will not update automatical when you change the Albums name.
if thats not what you want to hear ask more specific.
Actually you're not doing associations.
In object-oriented programming, you associate objects instead of "keys". There's no concept of "foreign key".
If an object B has a parent A, and A has an unique identifier, you won't associate B's parent by setting this unique identifier but the object itself:
B has a parent A:
public class A { public Guid ID { get; set; } }
public class B { public A Parent { get; set; } }
A someA = new A();
B someB = new B();
someB.Parent = someA;
Working this way, as "instance of A" may be associated with many other objects, changing the same object from any reference, will result in modifying that object.
How to achieve integrity constraints? There're some design patterns, but one of most common one is Specification.
That's creating a common interface "ISpecification" which has a method that may be called "Check", which accepts an argument - the object to check for an specification -. In implementations, this method will check that some object conforms some specification.
public interface ISpecification { bool Check(object some); }
public class Person { public string Name { get; set; } }
public class PersonSpecification : ISpecification
{
public bool Check(object some)
{
// Checks that some person won't be null and his/her name isn't null or empty
return some != null && !string.IsNullOrEmpty(((Person)some).Name);
}
}
This is a very simple and generic sample of how to implement business rules and/or constraints.
There're many frameworks which may help you in this area:
Microsoft Patterns & Practices Validation Block: http://msdn.microsoft.com/en-us/library/ff648831.aspx
NHibernate Validator: http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx (it's part of NHibernate project, but it can be consumed standalone without NHibernate).
In some projects I've integrated NHibernate Validator, and others, a custom solution based on Specification pattern, but in a more complex and flexible way than the sample.
About Specification pattern:
http://en.wikipedia.org/wiki/Specification_pattern
Related
So, I've got an aggregate( Project ) that has a collection of entities (ProjectVariables) in it. The variables do not have Ids on them because they have no identity outside of the Project Aggregate Root.
public class Project
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<ProjectVariable> ProjectVariables { get; set; }
}
public class ProjectVariable
{
public string Key { get; set; }
public string Value { get; set; }
public List<string> Scopes { get; set; }
}
The user interface for the project is an Angular web app. A user visits the details for the project, and can add/remove/edit the project variables. He can change the name. No changes persist to the database until the user clicks save and the web app posts some json to the backend, which in turns passes it down to the domain.
In accordance to DDD, it's proper practice to have small, succinct methods on the Aggregate roots that make atomic changes to them. Examples in this domain could be a method Project.AddProjectVariable(projectVariable).
In order to keep this practice, that means that the front end app needs to track changes and submit them something like this:
public class SaveProjectCommand
{
public string NewName { get; set; }
public List<ProjectVariable> AddedProjectVariables { get; set; }
public List<ProjectVariable> RemovedProjectVariables { get; set; }
public List<ProjectVariable> EditedProjectVariables { get; set; }
}
I suppose it's also possible to post the now edited Project, retrieve the original Project from the repo, and diff them, but that seems a little ridiculous.
This object would get translated into Service Layer methods, which would call methods on the Aggregate root to accomplish the intended behaviors.
So, here's where my questions come...
ProjectVariables have no Id. They are transient objects. If I need to remove them, as passed in from the UI tracking changes, how do identify the ones that need to be removed on the Aggregate? Again, they have no identification. I could add surrogate Ids to the ProjectVariables entity, but that seems wrong and dirty.
Does change tracking in my UI seem like it's making the UI do too much?
Are there alternatives mechanisms? One thought was to just replace all of the ProjectVariables in the Project Aggregate Root every time it's saved. Wouldn't that have me adding a Project.ClearVariables() and the using Project.AddProjectVariable() to the replace them? Project.ReplaceProjectVariables(List) seems to be very "CRUDish"
Am I missing something a key component? It seems to me that DDD atomic methods don't mesh well with a pattern where you can make a number of different changes to an entity before committing it.
In accordance to DDD, it's proper practice to have small, succinct
methods on the Aggregate roots that make atomic changes to them.
I wouldn't phrase it that way. The methods should, as much as possible, reflect cohesive operations that have a domain meaning and correspond with a verb or noun in the ubiquitous language. But the state transitions that happen as a consequence are not necessarily small, they can change vast swaths of Aggregate data.
I agree that it is not always feasible though. Sometimes, you'll just want to change some entities field by field. If it happens too much, maybe it's time to consider changing from a rich domain model approach to a CRUD one.
ProjectVariables have no Id. They are transient objects.
So they are probably Value Objects instead of Entities.
You usually don't modify Value Objects but replace them (especially if they're immutable). Project.ReplaceProjectVariables(List) or some equivalent is probably your best option here. I don't see it as being too CRUDish. Pure CRUD here would mean that you only have a setter on the Variables property and not even allowed to create a method and name it as you want.
I'm a novice trying to wrap my head around MVVM. I'm trying to build something and have not found an answer on how to deal with this:
I have several models/entities, some of which have logical connections and I am wondering where/when to bring it all together nicely.
Assume we have a PersonModel:
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And a ClubModel:
public class ClubModel
{
public int Id { get; set; }
public string Name { get; set; }
...
}
And we have MembershipModel (a Person can have several Club memberships):
public class MembershipModel
{
public int Id { get; set; }
public PersonId { get; set; }
public ClubId { get; set; }
}
All these models are stored somewhere, and the models are persisted "as in" in that data storage.
Assume we have separate repositories in place for each of these models that supplies the standard CRUD operations.
Now I want to create a view model to manage all Persons, e.g. renaming, adding memberships, etc. -> PersonMangementViewModel.
In order to nicely bind a Person with all its properties and memberships, I would also create a PersonView(?)Model that can be used in the PersonManagementViewModel. It could contain e.g. view relevant properties and also the memberships:
public class PersonViewModel : PersonModel
{
public Color BkgnColor { get return SomeLogic(); }
public IEnumerable<MembershipModel> { get; set; }
...
}
My question here is, how would I smartly go about getting the Membership info into the PersionViewModel? I could of course create an instance of the MemberShipRepo directly in the PersionViewModel but that seems not nice, especially if you have a lot of Persons. I could also create all repositories in the PersonManagementViewModel and then pass references into the PersonViewModel.
Or does it make more sense to create another layer (e.g. "service" layer) that returns primarily the PersonViewModel, therefore uses the individual repositories and is called from the PersonManagementViewModel (thus removing the burden from it and allowing for re-use of the service elsewhere)?
Happy to have pointed out conceptional mistakes or some further reading.
Thanks
You are creating separate model for each table I guess. Does not matter, but your models are fragmented. You can consider putting related data together using Aggregate Root and Repository per Aggregate root instead of per model. This concept is discussed under DDD. But as you said you are new to MVVM, there is already lot much to learn. Involving DDD at this stage will only complicate the things.
If you decide to keep the things as is, best and quick thing I can guess is what you are doing now. Get instance of model from data store in View Model (or whatever your location) and map somehow. Tools like Automapper are good but they does not fit each situation. Do not hesitate to map by hand if needed. You can also use mix approach (Automapper + map by hand) to simplify the things.
About service layer, sure... why not. Totally depends on you. If used, this layer typically contain your business logic, mapping, formatting of data, validations etc. Again, each of that thing is up to you.
My suggestions:
Focus on your business objectives first.
Design patterns are good and helpful. Those are extract of many exceptionally capable developers to solve specific problem. Do use them. But, do not unnecessarily stick to it. Read above suggestion. In short, avoid over-engineering. Design patterns are created to solve specific problem. If you do not have that problem, then do not mess-up your code with unnecessary pattern.
Read about Aggregate Root, DDD, Repository etc.
Try your best to avoid Generic Repository.
I have a large class, let's call it 'Country'. It has all kinds of properties like List States, Age, etc.
In real life, I am working on an ASP.NET application in which a user enrolls into a subscription for a service our client provides. This application form they need to fill out has many many properties and one of the main classes representing the data model is becoming too bloated, and so I want to break it into small classes via composition but still have properties on the subclasses linked to the parent class.
For this example to keep things simple and refer to the car example. So we have a class called Country that looks like this:
public static class WorldDatabase
{
public static List<Country> Countries {get;set;}
}
class Country
{
public int Age {get;set;}
public string Name{get;set;}
public List<State> States{get;set;}
}
class State
{
public string CountryName{get;set;}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
Now, creating a quick sample of the setup:
var states = new List<States>();
states.Add(new State(){CountryName="United States",
StateName="NJ",
Capitol="Trenton"});
WorldDatabase.Countries.Add(new Country{Age=237,
Name="United States",
States=states});
WorldDatabase.Countries[0].Name="US";
//assert obviously fails because the names are not linked
Assert.IsEqual(WorldDatabase.Countries[0].Name == states[0].CountryName);
So the problem I'm trying to solve: what's the best way to link the two properties? The way I came up with is injecting an instance of the parent (Country) into the State class. But I'm concerned about the child making changes to the parent when he shouldn't be. Also, it seems like there might be a way to do this with less code that I'm not aware of. Here's the two ways I came up with:
//does a one-time 'binding'
class State
{
public void BindFrom(Country country)
{
CountryName=country.Name;
}
public string CountryName{get;set;}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
//tracks the parent forever
class State
{
private readonly Country _parent;
public State(Country parent)
{
_parent = parent;
}
public string CountryName
{
get
{
return _parent.Name;
}
}
public string Capitol{get;set;}
public List<string> Cities{get;set;}
}
What's the name of this pattern (if it is one)? I'd like to read more about it.. and is there an alternative?
The only pattern I see that is close to your example is the Delegation Pattern (the retrieving of the name is delegated to the state's parent).
Your example reminds me of the difference between agregation and composition : a country has several states and it has no meaning to have a state which doesn't belong to a country.
I guess both solutions have their pros and cons. However I'd change the first one to only know the CountryName instead of passing the country in the constructor. What's the point of breaking data encapsulation with a public setter for CountryName if the country name is altered in a constructor?
Your probelem can be solved by using an interface or base class implemented/inherited by your parent classes.
The interface/base class should only expose the parameters that you wish the child to be able to see or modify. Only the full implementation should allow writing.
class CountryBase
{
public string Name { get; protected set; }
}
class Country: CountryBase
{
public string Name { get { return base.Name;} set { base.Name = value;}
}
Country now has full control of the setter for CountryBase.Name. Pass only CountryBase to your State instances.
Alternatively, as an interface (my recommendation);
class ICountry
{
string Name { get;}
}
class Country: ICountry
{
public string Name { get; set; }
}
It looks like State should have a reference to the Country it belongs to. This kind of pattern is called Object composition.
I don't know what pattern this is, but looking at your example I think the problem your facing is the possibility that a property content is changed and not all different objects that should share the same property contents change with it. If I'm mistaken let me know and I will remove my answer, because the following is based on this assumption.
Using a base class or an interface solve the problem. It just makes sure both have a property that have the same name. If it is at all possible. I would try to implement a different pattern.
One way of doing this is, you could create an object that has a reference in both the Country object and the State object. Than create an object call it Controller that controls the contents of the Name object. If the name has to change the controller is called and te contents is changed accordingly. Make sure the set the property on both the Country object and the State object to Readonly.
A more simple but just as effective way is to create a 'Controller' that is the only object that can change the properties. There does not need to be a reference between the two properties. If the controller is the only object that can change the properties make a method on the controller to change the name of United States to US. If the contoller knows about all collections of countries and states It can then change the properties by doing a lookup on the original content and change that to the new content. If the there are two controllers one for countries and one for states it can call a method on another controller to make the same change. (The existence of the kind of change method can be forced with an Interface or base class)
Think of it this way. A chair has a collection of legs, but the chair itself doesn't know this. It is just a chair. It is the user or owner of the chair the knows it has 4 legs. It could just as well have three legs. If a leg is broken you tell the carpenter to repair the leg of the chair. If you want to add an extra leg to a three legged chair, you tell the carpenter not the chair. In your case if the name of a country is changed you tell it to the country controller. Then the country name gets changed. The country itself just has a name.
The problem with this solution is that in a project that already has a large code base and many people have worked on this is just introducing yet another way of doing things. Old code might not follow your new way of doing things which makes it stand out odd to the rest of the code. Furthermore most of the time refactoring the whole code base isn't feasible nor advisable. Of course slowly introducing this new way might be an option.
I having an old puzzle, so I thought I'll share it with you, may be will get right direction.
Thing is, that some of our entities in database are quite big (read have many properties), and rarely business logic uses all of entity properties, so every time I need to think what properties must be loaded for business logic to work correctly. Very hypothetical sample:
public class Product
{
public string Title {get;set;}
public string Description {get;set;}
public string RetailPrice {get;set;}
public string SupplierId {get;set;}
public Supplier Supplier { get;set;}
// many other properties
}
public class ProductDiscountService
{
public decimal Get(Product product)
{
// use only RetailPrice and Supplier code
return discount;
}
}
public class ProductDescriptionService
{
public string GetSearchResultHtml(Product product)
{
// use only Title and Description
return html;
}
}
It looks like I could extract interfaces IDiscountProduct and ISearchResultProduct, mark product as implementing those interfaces, then create smaller DTOs implementing each of those interfaces, but that looks at the moment as overkill (at least I haven't seen anyone grouping properties using interfaces).
To split entity in database to smaller entities also doesn't look reasonable, as all those properties belong to product and I'm afraid I'll be forced to use many joins to select something and if I'll decide that some property belongs to another entity, that move will be quite hard to implement.
To have every property used in particular method's business logic as method parameter also looks like bad solution.
Unless the properties are big (read long strings and/or binaries) I'd just load them all.
The points below are for simple properties (e.g. Title)
No extra code (get this product with title only, or get with price only, blah-blah)
A product instance is always complete, so you can pass it around without checking if the property is null.
If you'll have to lazy-load some other properties, it'll cost you more than loading them eagerly. If you have like 20 properties - this isn't even a big object (again, if your (hypothetical) Description property is not kilobytes in size).
Now, if you have related objects (ProductSupplier) - this should be lazy-loaded, imo, unless you know this property will be used.
my name is aderson and in this moment i have something question about composition referents to performance. In this model
i have a simple userbase and departmentbase. The userbase have a property of type deparmentbase and departmentbase have a list property of type departmentbase.
When i have a instance of userbase in this moment load information about department but then DepartmentBase load information about Departments too!!!.
Now, when i have a list of userbase for all user the process load again for all users, this is a good practise or what is the better form?
alt text http://img146.imageshack.us/img146/3949/diagram.jpg
I don't know if it is a better (or even applicable) approach, but I sometimes make brief versions of objects that I use for references from other objects. The breif version acts as a base class for the full version of the object, and will typically contain the information that would be visible in a listing of such objects. It will often not contain lists of other objects, and any references to other classes will usually refer to the brief version of that class. This eliminates some unnecessary data loading, as well as some cases of circular references. Example:
public class DepartmentBrief
{
public string Name { get; set; }
}
public class Department : DepartmentBrief
{
public Department()
{
Departments = new List<DepartmentBrief>();
}
public IEnumerable<DepartmentBrief> Departments { get; private set; }
}
public class UserBase
{
public DepartmentBrief Department { get; set; }
}
One difference between this approach and having full object references paired with lazy loading is that you will need to explicitly load extra data when it is needed. If you have a UserBase instance, and you need the department list from the Department of that UserBase, you will need to write some code to fetch the Department object that the DepartmentBrief object in UserBase is identifying. This could be considered a downside, but I personally like the fact that it will be clear when looking at the code exactly when it is going to hit the data store.
It depends, if you need all the department data directly after loading the user list, then this is the best approach. If you don't need it immediately, you better use lazy loading for the department data. This means you postpone the loading of the department data until an explicit method (or property) has been called.