How should I refactor this design?
class Service : IChargeable, IExtendable<br />
{
}
interface IChargeable
{
decimal? ChargeableAmount {
get;
}
}
interface IExtendable
{
bool IsExtendable {
get;
}
}
class DayService : Service { }
class NightService : Service { }
class TwentFourService : Service { }
The problem is that these services are charged at varied rates, depending on whether they are extendable or depending on their type.
A percentage of the chargeable amount is charged if the service is extended. The service charge is ChargeableAmount * Seasonal rate, which differes for each service.
I do not want to store the rates in the Service Class or any of the derived classes. Would it be a good idea to create a SeasonalRate provider which has methods for each ServiceType which return the SeasonalRate?
The problem is that the seasonal rates can change and do change often and we are wary of making changes to the Service Classes. We would also like to have maintainable dependencies on the Service Classes in our SeasonalRates classes.
Is it a good idea to implement a SeasonalRates class with overloads for each ServiceClass (a sort of a visitor)? Would it be a problem that all SeasonalRates classes will have to implement methods for all ServiceTypes?
What interface should the SeasonalRate class implement as there will be other classes too which calculate rates such as DiscountRate, ZipCodeRate, etc.?
If more ServiceType classes are added, will it be difficult to maintain changes to all Visitors?
Edit: All rates vary by ServiceType. For example, SeasonalRates for Day and Night Services are different
What would be advantages/disadvantages of the approach suggested by Jeff Meatball Yang over using the standard visitor pattern like follows:
interface IVisitable
{
Accept(IVisitor visitor);
}
interface IVisitor
{
Visit(IVisitable visitable);
}
interface IRate
{
Rate { get; }
}
class Service : IVisitable
{
public virtual Accept(IVisitor visitor);
}
class Visitor : IVisitor
{
public virtual Visit(IVisitable visitable) { }
public virtual Visit(DayService visitable) { }
public virtual Visit(NightService visitable) { }
}
class RateVisitor : Visitor, IRateVisitor
{
decimal? _Rate;
override Visit(IVisitable visitable) { };
override Visit(DayService visitable) { // Logic Goes here, sets the _Rate Variable };
// Overrides for other services
public virtual Rate
{
return this._Rate;
}
}