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.
Related
Hi!
I am new to MVC and I don´t know if I am doing it right the way I try to do it, so I need your help.
Think about a trivial form with a listview on it (Just for example). Lets say the listview can hold multible student objects. This student objects consists just of a Name and a Id Number (As I mentioned very simple).
class student : IModel {
public string Name { get; set; }
public string IDNumber { get; set; }
}
interface IModel {
string Name { get; set; }
string IDNumber { get; set; }
}
When I use something like this as my model and I want to have a View as described above is it a good idea to encapsulate my "model" in some kind of a meta model?
Something like:
//in this example the IModel definition is not part of the student class
class studentModel : IModel {
List<student> Students { get; set; }
}
I hope you know what I am trying to explain.
I have to build a container for my model to be able to bind it to the View (So it is just one Model per View).
But if I do it like that my Student object is not part of IModel rather the studentModel is (e.g. to add Observer functionality). But if this is OK how should I access my student object in the View. Sure I can just access the component but is this a good approach? Is it better to build something like a model in a model?
I am a little bit confused as long as there is one student object in one view everything is ok but otherwise my brain is missing some information :)
I wouldn't create an interface (IModel), but rather a Student class only. An interface makes sense (generally speaking) when you want to establish a "contract" of some common behavior, that multiple implementers of that interface should use.
In the view side, the model that the view should accept would be something like List<Student> (note the capital S) and that's it.
As a side note, a good example of when you would want an interface is when there's some common characteristic (property) or funcionality (method) that you want to enforce. Let's say your system had not just students, but also professors and administrative staff. You could create an IPerson interface with just an Id as an enforced common property, then you would have classes Student, Professor, Staff that all implement IPerson and then all of them would be enforced, by the language, to have an Id property. And in that case you could even build a list view for example of people that its model is List<IPerson> (but then of course you'd have to do casting to access every property that's not Id...).
This is a pretty broad question, but if all you want to access in your view is a List<Foo>, there's nothing wrong with making that the model type. You don't need to enclose it in some other object.
Also (as Ofer has just posted) I'm not sure what purpose IModel serves here. Standard practice is to have your viewmodel exist for the sole purpose of containing the data for a given view. An interface would imply you intend to use it for something else.
Edit: If you like this answer accept Ofer's which was posted first and is identical.
I have a class with about 20 properties but I'd simplify it for this question:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
I'd like to have a class or property that identifies whether my class is dirty. By this I mean to identify whether any of its values have changed?
There are 3 design approaches I can take:
1)
When setting the property inside the class, I check whether the property IsDirty.
public string Name
{
get { return this._name; }
set { if (this._name != value) { this.IsDirty = true; this._name = value; }
}
2)
When setting the property from outside the class, I check whether the property IsDirty.
e.g.
if (p.Name != newName)
{
p.IsDirty = true;
p.Name = newName;
}
This approach forces me to add lots of ifs in the client class. Some properties are even collections or even reference objects so the number of lines would be increased even.
3)
When the object is ready to be saved, then I check whether any properties IsDirty by getting a cloned object and checking the equality.
This would have a poorer performance as I would have to clone or load again the original object then compare the properties one by one.
Which one is the best design? or is there any other design pattern that can help with this?
Another option would be to Implement the INotifyPropertyChanged Interface.
Please note that this will help you make thing more tidy and your API clearer, but as far as internal implementation regarding keeping track after changes, It is still up to you to implement. I think this goes along best with your Option #1
Option 1 is clearly best: it puts the responsibility of tracking dirtiness where it belongs: inside the object. Option 2 is out because as you mentioned, you are forcing this responsibility onto the clients of your classes. And option 3 has the additional problem as you mentioned of performance.
Incidentally, you should look into a proxy implementation using DynamicProxy. This will allow your code to look like this:
public class Product
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
and with the judicious use of interceptors, you can get the behaviour you want. You can write an interceptor to intercept any "sets" and do some logic inside, such as setting an IsDirty flag.
Another idea would be to make this a GoF Observable and let interested Observer parties register their interest in changes. It's a more event-based approach.
This is the best solution and complies with SRP principle very nicely, I created the below classes:
ProductWithChangeDetection; this uses the Decorator pattern to add this new feature to an existing product object
ProductChangeDetector; this contains logics for checking and notification. Currently only exposes ChangeDetected property but if more complexity needed one should implement INotifyPropertyChange interface.
ProductEquitable; this implements IEquitable and has some overloads for checking whether two objects/properties are equal
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.
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
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.