views:

67

answers:

3

I'm having something of a dilemma and would appreciate some input.

I have this class, let's call it "Car" where each instance has some individual settings (through properties), like "Color", "HasGearShift" or whatnot (I'm making this up for a simple example). These should be user customizable but there should also be default values.

So the natural solution was to take all the "settings" properties and break them into a separate "Settings" class which could be serialized/deserialized. Each Car class could also inherit the Settings class with one that sets the default values and can be serialized as the basis of user customization. Sofar so good.

The problem I feel though is that I either have to live with this kind of syntax all over the code: someCar.Settings.HasGearShift and there's even some like this: someCar.Settings.GearBox.CurrentGear But atleast there's no redundancy, everything is nicely encapsulated in the Settings class.

The other option is to keep the properties on the Car class and simply copy over them from the Settings class into the class. Then I can simply write someCar.HasGearShift again. Makes referencing properties a whole lot more terse but means I have to change settings in two classes if I add/remove something.

Which one would you choose, or is there a third better way that I am missing? I'm leaning towards the second option, otherwise there'll simply be too many "trainwrecks" in the code :)

+4  A: 

I think I would go for something in between: Use composition and make a CarSettings class with the needed settings, and make it serializable. Perhaps have a static CarSettings.Default property; that defines the default settings. Then the Car could take the settings instance in the constructor, and expose delegating properties for the settings, that needs to be externally visible.

Something along the lines of:

public class Car
{
    private CarSettings settings;

    public Car(CarSettings settings) 
    {
        settings = settings ?? CarSettings.Default;
    }

    public string Color { get {return settings.Color;} }
}

public class CarSettings 
{
     public string Color {get; private set;}
     public static CarSettings Default = new CarSettings {Color = "Red"};
}
driis
+1 I like this - while it doesn't solve the 'edit settings in two classes' but it does make the serializable 'settings' class like a DTO
n8wrl
I think you're right. I have something against "Pass-through properties" like that which feels like something of a hack, but in this case it might be the better of two evils and make the code much more readable
MattiasK
A: 

You could look at an existing design used by Visual Studio Win-forms designer:

Public Property AlternateItemColors() As Boolean Implements AbstractInterfaces.CoreControls.IVisualList.AlternateItemColors
    Get
        Return m_AlternateItemColors
    End Get
    Set(ByVal value As Boolean)
        m_AlternateItemColors = value
    End Set
End Property

Public Overridable Function ShouldSerializeAlternateItemColors() As Boolean
    If Me.AlternateItemColors = True Then Return False
    Return True
End Function

They also have a number of atrributes used, like; DefaultValue

eschneider
A: 

I'm not sure I see the problem here. It seems like your only issue is you don't like the deep nesting of properties. That's not a real problem, and you can easily just do this in your code when you need to access the settings:

var settings = someCar.Settings;
settings.Color...

What I'm trying to say is, your design seems fine, and the long syntax your worried about isn't an issue.

BFree
Well, the problem is that there's *alot* of those references sprinkled around the program so it does look quite messy, and adding one line like that in all the places it's used feels like it adds code unecessarily
MattiasK