Mixed vs. separated class mutability - class-design

In a partially mutable class, is it better to mix mutable fields with its immutable ones, or create a new class (or classes) that encapsulate them? Here's an example in C# of what I'm talking about:
interface IBedroom
{
int Volume { get; }
string Color { get; }
void Paint(string newColor);
}
Here's an implementation with mixed mutability in its fields:
class MixedMutabilityBedroom : IBedroom
{
readonly int volume;
string color;
public MixedMutabilityBedroom(int volume, string color = "")
{
this.volume = volume;
this.color = color;
}
public int Volume
{
get { return volume; }
}
public string Color
{
get { return color; }
}
public void Paint(string newColor)
{
color = newColor;
}
}
And one with separate mutability:
// first, a fully mutable helper class
class RoomColor
{
string value;
public RoomColor(string value)
{
this.value = value;
}
public string Value
{
get { return value; }
}
public void Change(string newValue)
{
value = newValue;
}
}
and the separated-mutability implementation:
class SeparatedMutabilityBedroom : IBedroom
{
readonly int volume;
readonly RoomColor color;
public SeparatedMutabilityBedroom(int volume, RoomColor color)
{
this.volume = volume;
this.color = color;
}
public int Volume
{
get { return volume; }
}
public string Color
{
get { return color.Value; }
}
public void Paint(string newColor)
{
color.Change(newColor);
}
}
I personally side with the latter style. In my experience, bugs that arise from state manipulation in concurrent scenarios are difficult to debug. As concurrency becomes the norm for programs, it seems that localizing mutability is a key factor to reducing debugging effort. In the second example we do not have to look over the entire class implementation to find out where state is manipulated. The entirety of SeparatedMutabilityBedroom's mutability is localized to RoomColor.
What do you think? Have I forgotten some points for consideration?

Programming with immutable data structures is a very useful technique but is hard to critique on an overall best practice or suggestion based on a simple example. Deciding what is best must take into account other factors such as how this class is being used and interacted with.
However, assuming you are in a situation that has a large amount of concurrency with multiple writers to this object, then making an object partially immutable really wont buy you much since you can still run into issues.
In that case either use some sort of synchronization primitive or use a completely immutable object.
This answer talks about some techniques of using completely immutable objects.

Related

Exercise 115; should I use getters/setters or something else?

I took care of exercise 105. I don't know what to do with 115 though. I've worked a little bit more and progressed a slight bit, but here's the exercise:
A team of biologists is conducting an experiment that involves collecting data on animals founds in a 1 km square area of woodland. As each animal is identified, a record is made of its name, the time of its discovery, and the initials of the scientist who found it. The data are to be recorded on a laptop. Design and implement a system for storing the data, and test your code thoroughly.
[Hint: Think in terms of creating an object for each discovery. What information should each object store, and in what will you store these objects?]
Here is my code:
// put class definitions here
public class Record{
String name;
String initials;
String time;
public Record{
this.name = name;
this.initials = initials;
this.time = time;
}
}
Here's another section for me to test my solution in:
public static void main( String[] args )
{
// test your solution here
}
So I know I'm supposed to make a new Object out of the variables, but do I need to use getters and setters or something? If that was the case it would probably be a lot easier than I'm assuming.
Thx
Getters and setters is a common pattern for getting internal member variables from Objects. They are not mandatory, but it is a good practice.
You need to read some Java and Object Oriented book to understand why we use it that way. You need to understand why encapsulation is encouraged too.
public class Record{
protected String name;
protected String initials;
protected String time;
public Record{
this.name = name;
this.initials = initials;
this.time = time;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
//... etc.
}

Dynamic way to Generate EntityTypeConfiguration : The type 'TResult' must be a non-nullable value type

I was thinking to generate EntityTypeConfiguration dynamically from run time and i don't want any EF dependency in Models[That is why i avoid Data Annotation].
So I declare a custom attribute(or can be any configuration file later on)
[AttributeUsage(AttributeTargets.Property, AllowMultiple=true )]
public class PersistableMemberAttribute : Attribute
{
public bool Iskey;
public bool IsRequired;
public bool IsIgnored;
public bool IsMany;
public string HasForeignKey;
public bool PropertyIsRequired;
public bool PropertyIsOptional;
}
And here is one of my Models is look like:
public class Blog
{
[PersistableMember(Iskey=true)]
public Guid BlogId { get; set; }
[PersistableMember(PropertyIsRequired = true)]
public string Name { get; set; }
public string Url { get; set; }
[PersistableMember(IsIgnored=true)]
public int Rating { get; set; }
[PersistableMember(IsMany =true)]
public ICollection<Post> Posts { get; set; }
}
Now I am going to write a generic EntityTypeConfiguration , which will create the configuration dynamically on run time based on the attribute values :
public class GenericEntityConfiguration<T> : EntityTypeConfiguration<T> where T : class
{
public GenericEntityConfiguration()
{
var members = typeof(T).GetProperties();
if (null != members)
{
foreach (var property in members)
{
var attrb= property.GetCustomAttributes(typeof( PersistableMemberAttribute ),false).OfType<PersistableMemberAttribute>();
if (attrb != null && attrb.Count() > 0)
{
foreach (var memberAttributute in attrb)
{
if (memberAttributute.Iskey || memberAttributute.IsIgnored)
{
var entityMethod = this.GetType().GetMethod("Setkey");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.IsRequired)
{
var entityMethod = this.GetType().GetMethod("SetRequired");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.PropertyIsRequired || memberAttributute.PropertyIsOptional)
{
var entityMethod = this.GetType().GetMethod("SetPropertyConfiguration");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
}
}
}
}
}
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.PropertyIsRequired)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
}
if (attribute.PropertyIsOptional)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
}
}
public void Setkey<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.Iskey)
{
this.HasKey<TResult>((Expression<Func<T,TResult>>)lambda);
}
if (attribute.IsIgnored)
{
this.Ignore<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
public void SetRequired<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) where TResult : class
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.IsRequired)
{
this.HasRequired<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
}
But i got the compilation error of
Error 1 The type 'TResult' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)' D:\R&D\UpdateStorePOC\UpdateStorePOC\Data\GenericEntityConfiguration.cs 63 17 UpdateStorePOC
which for these two statements:
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
that means that I need to put a constraint on my method to restrict it to a value type. In C#, this is done with the ‘struct’ keyword.
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) Where TResult : struct
But Its not the solution since my property type can be a class e.g string or int, bool double, etc . So it is not at all clear that I can send them into this method. Please help me to solve this issue whether there is any other way to do it.
I don't want any EF dependency in models.
With fluent mapping you're almost there and you won't come any closer. Your attributes, even though intended to be moved to a configuration file, don't make your model any more free of any EF footprint.1 Worse, they only add a second mapping layer (if you like) between your model and EF's mapping. I only see drawbacks:
You still have to maintain meta data for your model, probably not any less than regular fluent mapping and (probably) in awkward manually edited XML without compile-time checking.
You will keep expanding your code to cover cases that EF's mapping covers but yours doesn't yet.2 So it's a waste of energy: in the end you'll basically have rewritten EF's mapping methods.
You'll have to keep your fingers crossed when you want to upgrade EF.
With bugs/problems you're on your own: hard to get support from the community.
So my answer to your question help me to solve this issue would be: use fluent mapping out of the box. Keep it simple.
1 For example, you would still have to use the virtual modifier to enable proxies for lazy loading.
2 Like support for inheritance, unmapped foreign keys, max length, db data type, ... this could go on for a while.

Scala the default way to create objects that require a complex construction process

I think its always useful to know the default practices that the language designers intended, and the default practices towards which they target language improvements, even if one later deviates from those conventions. In Scala all fields have to be initialised in the constructor of the class they're declared in. This is a a significant restriction. Secondary constructors are also restricted. Any temporary variables in a constructor need to be placed in an inner method or closure, to avoid unwanted fields, which can make the body of a constructor look messy. All this militates against using constructor bodies. The override val/var syntax needed even when assigning to abstract variables from a super class remove some of the advantage of using derived classes for the sake of construction.
A companion object has access to all the fields of its class. However for construction this is not the advantage that it might first appear, as all fields must be initialised in the constructor of the class. So it would seem the natural practice is to use a method in an object to do any processing of the classes variables, creating a temporary mutable collection for each immutable collection in the class, listbuffer being the default and then pass all the values and collections into a bodiless constructor. The factory can be in any object or even class but might as well be in the companion object unless there's a good reason otherwise. Objects can't take type parameters but their factory methods can if needed. And of course you can have as many factory methods as you need quasi-constructors and they can reuse any common algorithms.
Is this correct?
In response to the request for an example, here's a constructor I'm in the process of porting across to Scala from C#, note the multiple type parameters are gone in Scala:
public class GridC : GridBase<HexC, SideC, UnitC, ISegC>
{
public Geometry<HexC, SideC, UnitC, ISegC> geomC { get; private set; }
internal GridC(Scen scen, int gridNum, int xDim, int yDim, int xOff, int yOff, Terr terr = Terr.Plain):
base(gridNum, scen, 10.0)
{
this.geomC = scen.geomC;
xIntLeft = xOff + 1;
yIntBottom = yOff;
xIntRight = xDim * 2 + 1 + xOff;
yIntTop = yDim * 2 + 2 + yOff;
Coodg hexCoodg;
for (int x = xOff; x < xDim * 2 + xOff; x += 2)
{
for (int y = yOff; y < yDim * 2 + yOff; y += 2)
{
if (x % 4 == y % 4)
{
hexCoodg = new Coodg(num, x + 2, y + 2);
HexC hexC = scen.hexCs.NewHexC(hexCoodg);
SideC sideC;
MiscStrat.sixDirn.ForEach(i =>
{
Coodg sideCoodg = hexCoodg + Cood.DirnTrans(i);
sideC = sides[sideCoodg];
if (sideC == null)
scen.sideCs.NewSide(hexC, i);
else
scen.sideCs.SetHex2(sideC, hexC, i);
});
}
}
}
}
The above sub class is created purely to provide a constructor for the following base class edited just to show the parts relevant to construction;
public class GridBase<HexT, SideT, UnitT, SegT> : IGridBase
where HexT : Hex where SideT : Side where UnitT : Unit where SegT : ISeg
{
public int num { get; private set; }
int IGridBase.num { get { return num; } }
IListsGeom<HexT, SideT, UnitT> iLists;
public HexList<HexT> hexs { get { return iLists.hexs; } }
public SideList<SideT> sides { get { return iLists.sides; } }
public Geometry<HexT, SideT, UnitT, SegT> geom { get; private set; }
public int xIntLeft { get; protected set; }
public int xIntRight { get; protected set; }
public int yIntBottom { get; internal set; }
public int yIntTop { get; internal set; }
public double scale { get; private set; }
protected GridBase(int num, IListsGeom<HexT, SideT, UnitT> iLists, double scale)
{
this.num = num;
this.iLists = iLists;
this.scale = scale;
}
}
The constructor creates a simple uniform Hex grid. Other constructors were required that used a completely different algorithm and others will be created that require a related but more complex algorithms. I'm not an expert but my impression is that factories are used a lot less in C#.
If I understand your question, I'd say that something that needs a complicated construction method should have apply methods to support that on the companion object. However I'd be concerned that they have such complicated construction requirements.
In general, you usually provide complex construction like this through methods on the companion object of your (base) class. It provides a nice clean separation of the initialisation code and the post-construction usage code.
Also, having immutable data may help design smaller, more focused concerns. For instance you have a box (left, right, top, bottom) that you could separate into its own class (or just a tuple if you like).
About your statement that all fields must be initialized in the constructor of the class: you have two ways to cope with this.
Set the more complicated fields to a default value in the constructor of the class, e.g. val a: Int = _
Do the calculations in the apply method of the companion object and initialize all fields in the constructor (i.e., pass all those pre-computed values to the constructor)
Personally, I prefer 2. because it guarantees that an object is semantically complete after construction.

what is use of creating property in separate class for each entilty?

I am learning some good code practice that's why i was going through some code, some thing i could not understand in it. It has made property in a separate class for each entity like in userClass it has property
#region public properties
private int uid;
public int userId
{
get { return uid; }
set { uid = value; }
}
private string uName;
public string userName
{
get { return uName; }
set { uName = value; }
}
private string pwd;
public string password
{
get { return pwd; }
// set { pwd = value; }
}
private string uAddress;
public string userAddress
{
get { return uAddress; }
set { uAddress = value; }
}
private string fName;
public string firstName
{
get { return fName; }
set { fName = value; }
}
private string lName;
public string lastName
{
get { return lName; }
set { lName = value; }
}
private string uPhone;
public string userPhone
{
get { return uPhone; }
set { uPhone = value; }
}
private string uMobile;
public string userMobile
{
get { return uMobile; }
set { uMobile = value; }
}
private int secretQuestion;
public int securityQuestion
{
get { return secretQuestion; }
set { secretQuestion = value; }
}
private string userAnswer;
public string answer
{
get { return userAnswer; }
set { userAnswer = value; }
}
#endregion
and from the business logic class it uses the property instead of using directly any entity's attribute name, but i am confuse whats there need to make a property like this?
other then this it has got enums for database column name which has a clear reason behind this that if in near future we have to change the database table's fields name then we don't have to change through out the whole business logic class and we can make changes to enum directly, But what is there use of creating property like this please elaborate me on this
Are you really asking why it uses properties instead of having public fields?
Fields are an implementation detail - they're how data is stored, which shouldn't be something the outside world cares about, at least for 99% of types. Properties are part of the contract that a type has in terms of its API - the implementation is up to the type. In other words, it's a matter of encapsulation. Properties can be expressed in interfaces, as abstract methods etc, precisely because they keep the contract and the implementation separate.
Additionally, properties make databinding, debugging and various other things simpler. I have an article about why properties matter, which you may find useful.
Having said all of this, those properties are implemented in a tedious way - and they don't obey .NET naming conventions. I would have written them as:
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
// etc
Properties can be defined on Interfaces, but member fields cannot. So if you needed to refactor this class to a class that implements an interface, you can put the properties on the interface (and then have other classes that implement them as well.)
Some similar questions:
Public Fields versus Automatic Properties
Property vs public field.
In additional to above: Actually you can easily decide public field or property by yourself. It is quite easier to understand that:
(1) Name is a property of class Person
(2) Speed is a property of class Plane
(3) Empty is a public field of class String. If you say String has a property named Empty, it's really weird. And String has a property Length is easy to understand.

MVVM-Pattern for a Diagraming Application with WPF - Convert enum to xxxViewModel

I'm trying to apply the MVVM design pattern to a diagramming application. In this application there are different items (for example a rectangle, a circle,...). I would like to save the item type as an enum in my model.
In my modelview I made a class for every item type (rectangleViewMode, circleViewMode,...).
On my view I apply a data template to the type, so it renders like a circle, or like a rectangle.
The problem is...how can I convert the enum in my model to the requiered xxxViewMode? I have a lot of types and I would like an automatic conversion.
I'm new to MVVM and maybe there is a better approach...so better solutions are welcome! :)
Thank you very much
I read your question a little differently to the other answerers, i don't believe you are just looking for a way to bind an enum to a combo, i think you are looking for a way to relate an enum value to an object type. If i got this wrong then stop reading now :)
First up: I'm not sure that saving the shape types as an enumeration (or even relating the shape to an enumeration) is very scalable. Read on, and i'll explain towards the end.
To relate an item type to an enum, just have the item return the appropriate enum value via a property:
public CircleViewMode
{
public ShapeType Shape { get { return ShapeType.Circle; }}
}
public enum ShapeType
{
Circle,
Square,
Rectangle,
Triangle,
FancyShape1,
FancyShape2
}
This means that you don't have to employ a converter or another translator mechanism. If you want to then populate a bunch of these into a combo then it is quite simple - check this following sample and insert breakpoints at the appropriate spot to see how it works.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Example().Run();
Console.ReadKey();
}
}
public class Example : INotifyPropertyChanged
{
public void Run()
{
var availableShapes = AllMyShapes.Where(x => x.NumberOfSides == 4);
AvailableShapes = new List<KeyValuePair<string, Type>>
(from Shape s in availableShapes
select new KeyValuePair<string, Type>(
Enum.GetName(typeof(ShapeType), s.ShapeType)
,s.GetType()
));
//at this point any combobox you have bound to the AvailableShapes property will now carry a new list of shapes
}
public List<Shape> AllMyShapes
{
get
{
return new List<Shape>() { new Circle(){NumberOfSides=1, ShapeType=ShapeType.Circle}
,new Square(){NumberOfSides=4, ShapeType=ShapeType.Square}
,new Rectangle(){NumberOfSides=4, ShapeType=ShapeType.Rectangle}
,new Triangle(){NumberOfSides=3, ShapeType=ShapeType.Triangle}
,new FancyShape1(){NumberOfSides=10, ShapeType=ShapeType.FancyShape1}
,new FancyShape2(){NumberOfSides=30, ShapeType=ShapeType.FancyShape2}
};
}
}
public List<KeyValuePair<string, Type>> AvailableShapes
{
get { return _availableShapes; }
protected set
{
_availableShapes = value;
}
}
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private List<KeyValuePair<string, Type>> _availableShapes;
public event PropertyChangedEventHandler PropertyChanged;
}
public abstract class Shape
{
public int NumberOfSides { get; set; }
public ShapeType ShapeType { get; set; }
}
public class Square : Shape { }
public class Rectangle : Shape { }
public class Triangle : Shape { }
public class Circle : Shape { }
public class FancyShape1 : Shape { }
public class FancyShape2 : Shape { }
public enum ShapeType
{
Circle,
Square,
Rectangle,
Triangle,
FancyShape1,
FancyShape2
}
}
With this approach you will have a combobox with nice human readable shape names in it, and you can instantly get the actual shape type of the selected item. It would be a trivial task to turn the class Example into an abstract base ViewModel, any ViewModel you then derive from it will have the AvailableShapes property.
But back to my original point of scalability - as you increase the shape types you also need to update the enumeration. This could be problematic if you ship libraries of new shapes or allow users to create their own. You may be better off saving it as myShape.GetType().ToString(), which returns a string value that can then be used to recreate the an instance of the object using reflection. In the above example of showing the items in a combo, you could just get a List<Type> of the available shapes and use a converter to produce a nice human readable name from the shape type (using a string resource file, eliminating the enumeration altogether).
Depending on your needs, you could use a converter class:
(stolen from How to bind RadioButtons to an enum?)
public class EnumBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
#endregion
}