I have inherited the following (terrible) code and am wondering how best to refactor it.
There are large if/else clauses all over the codebase, one of which is similar to below :
public class BaseResultItem
{
public int Property1 { get; set; }
}
public class ResultItem1 : BaseResultItem
{
public int Property2 { get; set; }
}
public class ResultItem2 : BaseResultItem
{
public int Property3 { get; set; }
}
public class BaseHistoryItem
{
public int Property1 { get; set; }
}
public class HistoryItem1 : BaseHistoryItem
{
public int Property2 { get; set; }
}
public class HistoryItem2 : BaseHistoryItem
{
public int Property3 { get; set; }
}
public class HistoryBuilder
{
public BaseHistoryItem BuildHistory(BaseResultItem result)
{
BaseHistoryItem history = new BaseHistoryItem
{
Property1 = result.Property1
};
if (result is ResultItem1)
{
((HistoryItem1)history).Property2 = ((ResultItem1)result).Property2;
}
else if (result is ResultItem2)
{
((HistoryItem2)history).Property3 = ((ResultItem2)result).Property3;
}
return history;
}
}
Note that this is a simplified example and there are many more classes involved in the actual code. There are similar if/else clauses all over the place.
I have been looking at the abstract factory pattern but I am having some problems.
Basically I am assuming that to avoid the if/else problems I need to pass the actual dervied types around. So BuildHistory should not use base types and maybe there should be multiple methods, one per derived type?
If you can't change the DTO classes perhaps you can try to subclass HistoryBuilder to deal with the different subclasses. Then you use the appropriate HistoryBuilderX to create a HistoryItem from a ResultItem. Then the question is how to get the appropriate HistoryBuilderX for the ResultItem supplied.
Still, if you can't change the BaseResultItem class to include a GetBuilder function you need to use some if..else if.. construct that inspects the classtypes of your ResultItems.
Or you create a Registry where every ResultItem class is registered with its corresponding HistoryBuilderX class. But that might be overkill.
The general 'design pattern' is simply to use object orientation with polymorphism instead of type checks. Thus: a BuildHistory method inside BaseResultItem, overridden by descendants.
Any code which checks the concrete type of an object smells (in a refactoring sense). Supporting different behaviours for different types is what OO is about.
Use polymorphism to remove the type checks.
if (result is ResultItem1)
{
((HistoryItem1)history).Property2 = ((ResultItem1)result).Property2;
}
Becomes then something like
result.addToHistory( history );
If for some reason, you don't want to scatter the logic in the item classes, have a look at the visitor pattern. In this case, you have something like:
public class Visitor {
History history;
public visit ( ResultItem1 item ) { ... }
public visit ( ResultItem2 item ) { ... }
...
}
public class ResultItem1 {
public accept( Visitor v ) { v.visit( this ); }
}
The typecheck is removed by the double-dispatch in the visitor, which is slightly more elegant.
I didn't understood exactly how the various kind of history relates to the various kind of items. So this is just a sketch of possibles direction to follow.
Related
Is it advisable to use the "new" keyword in a derived interface to provide a more-derived return value for a property or method having the same name?
Say I have an interface IDocument:
public interface IDocument
{
IParagraphs Paragraphs { get; }
IRevisions Revisions { get; }
IStyles Styles { get; }
}
And a derived one IRtfDocument.
public interface IRtfDocument: IDocument
{
string Rtf { get; }
...
}
I also have more-derived interfaces for IParagraphs, IRevisions and IStyles: IRtfParagraphs, IRtfRevisions, IRtfStyles. A number of RTF-specific needs drove their creation.
When I access the paragraphs of an RTF document, I'd like to avoid casting them to IRtfParagraphs. Same for revisions and styles. It would also be nice to avoid having both "IRtfParagraphs" and "IParagraphs". So what I'd like to do is this:
public interface IRtfDocument : IDocument
{
new IRtfParagraphs Paragraphs { get; }
new IRtfRevisions Revisions { get; }
new IRtfStyles Styles { get; }
string Rtf { get; }
}
Is this considered good practice? It seems to fit in this situation, but I wanted to run it by you C# veterans.
Update: So I actually went ahead and tried using "new" as described in my interfaces. My RtfDocument class ended up needing both an IDocument.Styles property and an IRtfDocument.Styles property. While I could just have the IDocument.Styles property return the value of IRtfDocument.Styles, that doesn't feel quite right as I'm implementing two properties.
It seems the compiler doesn't account for the fact that IRtfStyles derives from IStyles, so it insists I have both. It would be nice if the Liskov Substitution Principle let me just implement IRtfDocument.Styles in the RtfDocument class.
The easier solution would probably just be to have a generic interface:
public interface IFooBox<T>
where T : IFoo
{
T Foo { get; }
}
You can then have an IFooBox<IFoo> for your basic objects, or an IFooBox<IEnhancedFoo> for the enhanced version.
This type of definition will force implementers of IEnhancedFooBox to explicitly implement IFoo.Foo separately from the implementation of IEnhancedFooBox.Foo. Since this work gets tedious, I tend to reserve this for cases where a generic interface extends a non-generic interface.
For example, consider the following interfaces.
interface IFutureValue {
object Result { get; }
}
interface IFutureValue<T> : IFutureValue {
new T Result { get; }
}
It is possible to implement a general handler for all "future values" by working with IFutureValue, where code working with future values of a specific type can work with IFutureValue<T>.
To answer the question,
Is this considered good practice?
The use of new is frowned upon, in general. However, as with all frowning in programming, it is a matter of judgement. If you have found a use for new that makes sense in your context, and you've ruled out other avenues like #Servy's example, then rock the new. Be prepared to defend your decision though.
There is big potential problem with your use of the new modifier. Suppose we use your interfaces:
public interface IFoo
{
string Name { get; set; }
}
public interface IEnhancedFoo : IFoo
{
int BarCount { get; set; }
}
public interface IFooBox
{
IFoo Foo { get; set; }
}
public interface IEnhancedFooBox : IFooBox
{
new IEnhancedFoo Foo { get; set; }
}
Build out our classes:
public class EnhancedFooBox : IEnhancedFooBox
{
public IEnhancedFoo Foo { get; set; }
IFoo IFooBox.Foo { get; set; }
}
public class FooBase : IFoo
{
public string Name { get; set; }
}
public class EnhancedFoo : IEnhancedFoo
{
public int BarCount { get; set; }
public string Name { get; set; }
}
Build some methods that take interfaces...
static void Test1(IFooBox myBlah)
{
myBlah.Foo = new FooBase();
myBlah.Foo.Name = "FooBase";
}
static void Test2(IEnhancedFooBox myBlah)
{
myBlah.Foo = new EnhancedFoo();
myBlah.Foo.Name = "EnhancedFoo";
}
And then use this logic:
static void Main(string[] args)
{
var myBlah = new EnhancedFooBox();
Test2(myBlah); //first assign name to EnhancedFoo
Test1(myBlah); //second assign name to FooBase
Console.Write(myBlah.Foo.Name);
Console.ReadKey();
}
What is the expected output? Should it be FooBase or EnhancedFoo?
EnhancedFoo
Programmers unaware the property has been modified to new, will not get the expected output. This is solved using generics.
I am struggling to adhere to Liskov substitution principle when creating my class structure. I want to have a Collection of calendar items stored within a Day class. There need to be several different type of CalendarItems e.g:
AppointmentItem
NoteItem
RotaItem
they all share some common functionality which is presnt in the abstract base class CalendarItem:
public abstract class CalendarBaseItem
{
public string Description { get; private set; }
public List<string> Notes { get; private set; }
public TimeSpan StartTime { get; private set; }
public TimeSpan EndTime { get; private set; }
public int ID { get; private set; }
public DateTime date { get; private set; }
code omitted...
}
but then for example RotaItem has some extra functionality:
public class RotaItem : CalendarBaseItem
{
public string RotaName { get; private set; }
private bool spansTwoDays;
public bool spanTwoDays()
{
return this.spansTwoDays;
}
}
the other classes also add there own logic etc.
I have a collection of CalendarBaseItem for my day class:
List<CalendarBaseItem> calendarItems;
but on reviewing this I can see that I am breaking LSP principles as I have to check and cast each concrete type to get at the functionality that I desire for each subclass.
I would be grateful if someone could advise how to avoid this problem. Should I use a composition approach and add a CalendarItem class to each of the final classes e.g
public class RotaItem
{
private CalendarBaseItem baseItem;
public string RotaName { get; private set; }
private bool spansTwoDays;
public RotaItem(baseArgs,rotaArgs)
{
baseItem = new CalendarBaseItem(baseArgs);
}
public bool spanTwoDays()
{
return this.spansTwoDays;
}
}
The only problem here is that I will then need a seperate collection for each Concrete CalendarItem in my Day class?
I think what you're encountering is not so much a Liskov Substitution Principle violation as you are encountering a polymorphism limitation in most languages.
With something like List<CalendarBaseItem> the compiler is inferring that you're only dealing with CalendarBaseItem which obviously can't be true if CalendarBaseItem is abstract--but that's what a strongly-typed language does: It's only been told about CalendarBaseItem so that's what it limits usage to.
There are patterns that allow you to deal with this sort of limitation. The most popular is the double-dispatch pattern: a specialization of multiple dispatch that dispatches method calls to the run-time type. This can be accomplished by providing an override, that when dispatched, dispatches the intended method. (i.e. "double dispatch"). It's hard to associate exactly to your circumstances because of the lack of detail. But, if you wanted to do some processing based on some sort of other type for example:
public abstract class CalendarBaseItem
{
abstract void Process(SomeData somedata);
//...
}
public class RotaItem : CalendarBaseItem
{
public override void Process(SomeData somedata)
{
// now we know we're dealing with a `RotaItem` instance,
// and the specialized ProcessItem can be called
someData.ProcessItem(this);
}
//...
}
public class SomeData
{
public void ProcessItem(RotaItem item)
{
//...
}
public void ProcessItem(NoteItem item)
{
//...
}
}
which would replace something like:
var someData = new SomeData();
foreach(var item in calendarItems)
someData.ProcessItem(item);
Now, that's the "classical" way of doing in in C#--which spans all versions of C#. With C# 4 the dynamic keyword was introduced to allow run-time type evaluation. So, you could do what you want without having to write the double-dispatch yourself simply by casting your item to dynamic. Which forces the method evaluation to occur at run-time and thus will chose the specialized override:
var someData = new SomeData();
foreach(var item in calendarItems)
someData.ProcessItem((dynamic)item);
This introduces potential run-time exceptions that you'd likely want to catch and deal with--which is why some people don't like this so much. It's also currently very slow in comparison, so it's not recommended in tight loops that are performance sensitive.
I have a group of POCO classes:
class ReportBase
{
public string Name { get; set; }
public int CustomerID { get; set; }
}
class PurchaseReport : ReportBase
{
public int NumberOfPurchases { get; set; }
public double TotalPurchases { get; set; }
public bool IsVip { get; set; }
}
class SaleReport : ReportBase
{
public int NumberOfSales { get; set; }
public double TotalSales { get; set; }
}
I have a web method to return ReportBase. The caller uses the return value to update UI(WPF) based on the actually type by downcasting and checking the type (one grid for sale and one for purchase). Someone suggested to use three web methods and each return the specific type.
I understand that downcast is in general against design principle by introducing if/else. Instead we should use virtual functions. But in POCO class, we don't really have virtual behaviors (only extra fields).
Are you for or against downcast in this case, why?
IMO it's all about intention. Returning just the base class doesn't say anything, especially as you return it only to save some key strokes. As a developer what do you prefer?
ReportBase GetReport() // if type==x downcast.
//or
PurchaseReport GetPurchaseReport()
SaleReport GetSalesReport()
What approach would you want to use to make the code more maintainable? Checking type and downcasting is an implementation detail after all and you probably have a method like this
public void AssignReport(ReportBase report)
{
//check, cast and dispatch to the suitable UI
}
What's wrong with this? It's lacking transparency, and this method should always know about what reports are needed by what UI elements. Any time you add/remove an element you have to modify this method too.
I think is much clear and maintainable something like this
salesGrid.DataSource=repository.GetSalesReport();
purchaseGrid.DataSource=repository.GetPurchaseReport();
than this
var report=repository.GetReport();
AssignReport(report); //all UI elements have their data assigned here or only 2 grids?
So I think that, POCO or not, I will favour the three web methods approach.
In my current project I need to be able to have both editable and read-only versions of classes. So that when the classes are displayed in a List or PropertGrid the user is not able to edit objects they should not be allowed to.
To do this I'm following the design pattern shown in the diagram below. I start with a read-only interface (IWidget), and then create an edtiable class which implements this interface (Widget). Next I create a read-only class (ReadOnlyWidget) which simply wraps the mutable class and also implements the read only interface.
I'm following this pattern for a number of different unrelated types. But now I want to add a search function to my program, which can generate results that include any variety of types including both mutable and immutable versions. So now I want to add another set of interfaces (IItem, IMutableItem) that define properties which apply to all types. So IItem defines a set of generic immutable properties, and IMutableItem defines the same properties but editable. In the end a search will return a collection of IItems, which can then later be cast to more specific types if needed.
Yet, I'm not sure if I'm setting up the relationships to IMutable and IItem correctly. Right now I have each of the interfaces (IWidget, IDooHickey) inheriting from IItem, and then the mutable classes (Widget, DooHickey) in addition also implement IMutableItem.
Alternatively, I was also thinking I could then set IMutableItem to inherit from IItem, which would hide its read-only properties with new properties that have both get and set accessors. Then the mutable classes would implement IMutableItem, and the read-only classes would implement IItem.
I'd appreciate any suggestions or criticisms regarding any of this.
Class Diagram
Code
public interface IItem
{
string ItemName { get; }
}
public interface IMutableItem
{
string ItemName { get; set; }
}
public interface IWidget:IItem
{
void Wiggle();
}
public abstract class Widget : IWidget, IMutableItem
{
public string ItemName
{
get;
set;
}
public void Wiggle()
{
//wiggle a little
}
}
public class ReadOnlyWidget : IWidget
{
private Widget _widget;
public ReadOnlyWidget(Widget widget)
{
this._widget = widget;
}
public void Wiggle()
{
_widget.Wiggle();
}
public string ItemName
{
get {return _widget.ItemName; }
}
}
public interface IDoohickey:IItem
{
void DoSomthing();
}
public abstract class Doohickey : IDoohickey, IMutableItem
{
public void DoSomthing()
{
//work it, work it
}
public string ItemName
{
get;
set;
}
}
public class ReadOnlyDoohickey : IDoohickey
{
private Doohickey _doohicky;
public ReadOnlyDoohickey(Doohickey doohicky)
{
this._doohicky = doohicky;
}
public string ItemName
{
get { return _doohicky.ItemName; }
}
public void DoSomthing()
{
this._doohicky.DoSomthing();
}
}
Is it OK to create another object when you need a readonly copy? If so then you can use the technique in the included code. If not, I think a wrapper is probably your best bet when it comes to this.
internal class Test
{
private int _id;
public virtual int ID
{
get
{
return _id;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
private string _name;
public virtual string Name
{
get
{
return _name;
}
set
{
if (ReadOnly)
{
throw new InvalidOperationException("Cannot set properties on a readonly instance.");
}
}
}
public bool ReadOnly { get; private set; }
public Test(int id = -1, string name = null)
: this(id, name, false)
{ }
private Test(int id, string name, bool readOnly)
{
ID = id;
Name = name;
ReadOnly = readOnly;
}
public Test AsReadOnly()
{
return new Test(ID, Name, true);
}
}
I would suggest that for each main class or interface, there be three defined classes: a "readable" class, a "changeable" class, and an "immutable" class. Only the "changeable" or "immutable" classes should exist as concrete types; they should both derive from an abstract "readable" class. Code which wants to store an object secure in the knowledge that it never changes should store the "immutable" class; code that wants to edit an object should use the "changeable" class. Code which isn't going to write to something but doesn't care if it holds the same value forever can accept objects of the "readable" base type.
The readable version should include public abstract methods AsChangeable(), AsImmutable(), public virtual method AsNewChangeable(), and protected virtual method AsNewImmutable(). The "changeable" classes should define AsChangeable() to return this, and AsImmutable to return AsNewImmutable(). The "immutable" classes should define AsChangeable() to return AsNewChangeable() and AsImmutable() to return this.
The biggest difficulty with all this is that inheritance doesn't work terribly well if one tries to use class types rather than interfaces. For example, if one would like to have an EnhancedCustomer class which inherits from BasicCustomer, then ImmutableEnhancedCustomer should inherit from both ImmutableBasicCustomer and ReadableEnhancedCustomer, but .net doesn't allow such dual inheritance. One could use an interface IImmutableEnhancedCustomer rather than a class, but some people would consider an 'immutable interace' to be a bit of a smell since there's no way a module that defines an interface in such a way that outsiders can use it without also allowing outsiders to define their own implementations.
Abandon hope all ye who enter here!!!
I suspect that in the long run your code is going to be very confusing. Your class diagram suggests that all properties are editable (or not) in a given object. Or are your (I'm)mutable interfaces introducing new properties that are all immutable or not, separate from the "core"/inheriting class?
Either way I think you're going to end up with playing games with property name variations and/or hiding inherited properties
Marker Interfaces Perhaps?
Consider making all properties in your classes mutable. Then implement IMutable (I don't like the name IItem) and IImutable as a marker interfaces. That is, there is literally nothing defined in the interface body. But it allows client code to handle the objects as a IImutable reference, for example.
This implies that either (a) your client code plays nice and respects it's mutability, or (b) all your objects are wrapped by a "controller" class that enforces the given object's mutability.
Could be too late :-), but the cause "The keyword 'new' is required on property because it hides property ..." is a bug in Resharper, no problem with the compiler. See the example below:
public interface IEntityReadOnly
{
int Prop { get; }
}
public interface IEntity : IEntityReadOnly
{
int Prop { set; }
}
public class Entity : IEntity
{
public int Prop { get; set; }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var entity = new Entity();
(entity as IEntity).Prop = 2;
Assert.AreEqual(2, (entity as IEntityReadOnly).Prop);
}
}
Same for the case without interfaces. The only limitation, you can't use auto-properties
public class User
{
public User(string userName)
{
this.userName = userName;
}
protected string userName;
public string UserName { get { return userName; } }
}
public class UserUpdatable : User
{
public UserUpdatable()
: base(null)
{
}
public string UserName { set { userName = value; } }
}
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var user = new UserUpdatable {UserName = "George"};
Assert.AreEqual("George", (user as User).UserName);
}
}
I understand how the "new" keyword can hide methods in a derived class. However, what implications does it have for classes that implement interfaces that use the keyword?
Consider this example, where I decide to expand an interface by making its properties read/write.
public interface IReadOnly {
string Id {
get;
}
}
public interface ICanReadAndWrite : IReadOnly {
new string Id {
get;
set;
}
}
Then you are able to do things like this:
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
Is this bad design? Will it cause issues for my classes that implement ICanReadAndWrite?
Edit: Here is a contrived example of why I might want to do something like this:
Say I have a factory class that returns an IShoppingCartItemReadWrite. I can then have a service layer that manipulates prices on it, changes stuff, etc. Then, I can pass these objects as IShoppingCartItemReadOnly to some kind of presentation layer that won't change them. (Yes, I know it technically can change them-- this is a design question, not security, etc.)
It's not a particularly bad idea. You should be aware that the implementor can (if it implicitly implements the interface, then a single read/write property could satisfy both interfaces) provide two distinct implementations:
class Test : ICanReadAndWrite {
public string Id {
get { return "100"; }
set { }
}
string IReadOnly.Id {
get { return "10"; }
}
}
Test t = new Test();
Console.WriteLine(t.Id); // prints 100
Console.WriteLine(((IReadOnly)t).Id); // prints 10
By the way, in general, the new inheritance modifier does nothing except to tell the compiler to shut up and don't throw out a "you're hiding that member" warning. Omitting it will have no effect in the compiled code.
You should not implement the ICanReadWrite based on IReadOnly, but instead make them separate.
ie. like this:
public interface IReadOnly
{
string Id
{
get;
}
}
public interface ICanReadAndWrite
{
string Id
{
get;
set;
}
}
Here's a class using them:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
}
Note that the same property in the class can support both interfaces.
Note that as per the comment, the only way to get a robust solution would be to also have a wrapper object.
In other words, this is not good:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return this;
}
}
as the caller can just do this:
ICanReadWrite rw = obj.AsReadOnly() as ICanReadWrite;
rw.Id = "123";
To get a robust solution, you need a wrapper object, like this:
public class SomeObject : IReadOnly, ICanReadWrite
{
public string Id
{
get;
set;
}
public IReadOnly AsReadOnly()
{
return new ReadOnly(this);
}
}
public class ReadOnly : IReadOnly
{
private IReadOnly _WrappedObject;
public ReadOnly(IReadOnly wrappedObject)
{
_WrappedObject = wrappedObject;
}
public string Id
{
get { return _WrappedObject.Id; }
}
}
This will work, and be robust, right up until the point where the caller uses reflection.
This is perfectly legal and the implications for your class that implements the ICanReadAndWrite interface would simply be that when it is treated as an IReadOnly it can only read, but when treated as ICanReadAndWrite it would be able to do both.
I'm not sure if that compiles or not, but is not an advisable pattern to follow. With the ability to do explicit interface implementation, you could theoretically provide two entirely different implementations for the IReadOnly and ICanReadAndWrite versiond of the Id property. Consider altering the ICanReadAndWrite interface by adding a setter method for the property rather than replacing the property.
You can do it but I am not sure what you hope to accomplish by doing it.
public IReadOnly SomeMethod() {
// return an instance of ICanReadAndWrite
}
This method will return a reference to an IReadOnly which means that it doesn't matter that you have returned an ICanReadAndWrite. Wouldn't this approach be better?
public interface IReadOnly
{
String GetId();
}
public interface ICanReadAndWrite : IReadOnly
{
String SetId();
}