Work in C#, want to reduce if else series, entity have two property FromServiceID and ToServiceID ,suppose my ServiceClass instance have bellow information.How to clean up bellow code? any type of suggestion will be acceptable.
entity= new ServiceClass();
entity.FromServiceID=3
entity.ToServiceID=1
if (entity.FromServiceID == 1)
{
entity.1KWithdrawal();
}
else if (entity.FromServiceID == 2)
{
entity.10KWithdrawal();
}
else if (entity.FromServiceID == 3)
{
entity.BTWithdrawal();
}
if (entity.ToServiceID == 1)
{
entity.1KDeposit();
}
else if (entity.ToServiceID == 2)
{
entity.10KDeposit();
}
else if (entity.ToServiceID == 3)
{
entity.BTDeposit();
}
public class ServiceClass
{
public int FromServiceID { get; set; }
public int ToServiceID { get; set; }
public void 1KWithdrawal()
{ Console.WriteLine("One_KWithdrawal"); }
public void 10KWithdrawal()
{ Console.WriteLine("Ten_KWithdrawal"); }
public void BTWithdrawal()
{ Console.WriteLine("BTWithdrawal"); }
public void 1KDeposit()
{ Console.WriteLine("One_KDeposit"); }
public void 10KDeposit()
{ Console.WriteLine("Ten_KDeposit"); }
public void BTDeposit()
{ Console.WriteLine("Ten_KDeposit"); }
}
Use a Dictionary. Something like this:
Dictionary<int, ServiceClass> dictionary = new Dictionary<int, ServiceClass>()
{
{1, new ServiceClass()},
{2, new ServiceClass()},
{3, new BTWithdrawal()},//assume BTWithdrawal inherits from ServiceClass
};
An example of how using it:
ServiceClass value=new ServiceClass();
value.FromServiceId=1;
value.ToServiceId = 2;
dictionary.TryGetValue(value.FromServiceId, out value);
//or dictionary.TryGetValue(value.ToServiceId, out value);
if (value != null) MessageBox.Show(value.Id.ToString());
Maybe this is an overkill, but you can create a class for each one of your cases that inherits from a common interface (let's call it ICommon) that exposes a common method for each case (in your case a Create method) and then inject that interface in the constructor of ServiceClass.
Then when you want to use ServiceClass, you will have to provide an actual implementation of ICommon (one of the classes you extracted from each case) and finally you only have to call entity.Create.
I believe this is the strategy pattern, that in summary says that you should extract an algorithm in a different class under a common interface.
Finally, this refactoring will reduce the cyclotomic complexity of your code (this mainly means that you reduce the branching on your code) which always a good thing.
What you could do is to put all the variations into an enum and call the enum values exactly like your methods that you would like to call. (I would suggest not to use numbers in the name, since the compiler won't allow it)
For the sake of simplicity and testability I put the enum and the methods into the same class:
public class ServiceClass
{
public enum ServiceID
{
OneKWithdrawal,
Ten_KWithdrawal,
BTWithdrawal,
OneKDeposit,
Ten_KDeposit,
BTDeposit
}
public ServiceID From_Ser_ID { get; set; }
public ServiceID To_Ser_ID { get; set; }
public void One_KWithdrawal()
{ Console.WriteLine("One_KWithdrawal"); }
public void Ten_KWithdrawal()
{ Console.WriteLine("Ten_KWithdrawal"); }
public void BTWithdrawal()
{ Console.WriteLine("BTWithdrawal"); }
public void One_KDeposit()
{ Console.WriteLine("One_KDeposit"); }
public void Ten_KDeposit()
{ Console.WriteLine("Ten_KDeposit"); }
}
This would be the method that would execute your if-condition methods. It uses reflection to access the methods that are coded in the enum. You probably have to adjust the object parameter in the Invoke(sc, null); call depending on where your methods are situated. If they are in the same class as where you would call execute you can use this.
public static void execute(ServiceClass sc)
{
sc.GetType().GetMethod(sc.From_Ser_ID.ToString()).Invoke(sc, null);
sc.GetType().GetMethod(sc.To_Ser_ID.ToString()).Invoke(sc, null);
}
And here you can test the entire code:
public static void Main(string[] args)
{
ServiceClass entity = new ServiceClass();
entity.From_Ser_ID = ServiceClass.ServiceID.BTWithdrawal;
entity.To_Ser_ID = ServiceClass.ServiceID.Ten_KDeposit;
execute(entity);
}
So you would end up with an enum and 2 lines of code.
You can use switch case as below:
var entity = new ServiceClass();
entity.FromServiceID = 3;
entity.ToServiceID = 1;
switch(entity.FromServiceID)
{
case 1:
new 1KWithdrawal();
break;
case 2:
new 10KWithdrawal();
break;
case 3:
new BTWithdrawal();
break;
}
switch(entity.ToServiceID)
{
case 1:
new 1KDeposit();
break;
case 2:
new 10KDeposit();
break;
case 3:
new BTDeposit();
break;
}
Related
Long story short, i have following class:
public class FlowBasePipeline<T>
{
private List<StepBaseBusiness<T>> stepList = new List<StepBaseBusiness<T>>();
public void Push(StepBaseBusiness<T> step)
{
stepList.Add(step);
}
public void Trigger(T result)
{
foreach (var step in stepList )
{
result = step.Execute(result);
if (!result.IsSuccess)
{
break;
}
}
}
}
What I'm looking for is forcing programmer to call Push method in the first place and then give them access to Trigger method, in this case following scenario is not allowed
var pipeline=new FlowBasePipeline<MyStepResult>();
pipeline.Trigger()// Trigger method is not recognized
we should first call Push method
var pipeline=new FlowBasePipeline<MyStepResult>();
pipeline.Push(new MyStep()).Trigger()//Now Trigger is recognized
What I've done:
I applied explicit interface method implementation as follows to get it to work:
public interface IBasePipeline<T> where T:BaseResult,new()
{
void Trigger();
IBasePipeline<T> Push(StepBaseBusiness<T> step);
}
public class FlowBasePipeline<T>:IBasePipeline<T> where T:BaseResult,new()
{
private List<StepBaseBusiness<T>> stepList = new List<StepBaseBusiness<T>>();
public IBasePipeline<T> Push(StepBaseBusiness<T> step)
{
stepList.Add(step);
return this;
}
void IBasePipeline<T>.Trigger(T result)
{
foreach (var step in stepList )
{
result = step.Execute(result);
if (!result.IsSuccess)
{
break;
}
}
}
}
Now it works well and we don't have access to Trigger method before Push method, but from my prospective it's not a good way as we might need more level of orders and i don't know how it could be done in this way.
As i know, method chaining is one of the key rules of functional programming.
Is there any pattern or strategy to implement this kind of chaining?
Update:
we need to call push method multiple times
var pipeline=new FlowBasePipeline<MyStepResult>();
pipeline.Push(new MyStep1()).Push(new MyStep2()).Trigger();
After first push, push and trigger would be available.
One way to do this is to use interfaces to restrict access to specific methods by specifying an interface as the result.
public interface IStartCar
{
IDriveCar Start(string key);
}
public interface IDriveCar
{
IParkCar Drive(string address);
}
public interface IParkCar
{
IStopCar Park();
}
public interface IStopCar
{
IParkCar Drive(string address);
void Stop();
}
public class Car : IStartCar, IDriveCar, IParkCar, IStopCar
{
public IDriveCar Start(string key);
public IParkCar Drive(string address);
public IStopCar Park();
public IStopCar Park();
private Car() { }
public static IStartCar Get()
{
var result = new Car();
return result;
}
}
Now to get a Car you use the CarFactory method Get(), it returns a car, but you really only have access to the interface result. This pattern only allows developers to string specific methods together:
var car = Car.Get();
car.Start("key").Drive("address1").Park().Drive("address2").Park().Stop();
Example of approach I use for api's that inherently 'guide' the callers with a fluent syntax:
public class Pipeline
{
readonly List<Action> _steps = new List<Action>();
// only Push is available when Pipeline is initialized
public PipelineWithSteps Push(Action step)
{
_steps.Add(step);
// or cache this if you want 'Push' repeatable
return new PipelineWithSteps(this);
}
public class PipelineWithSteps
{
// not required but often the chained context wants/needs access to the first context
readonly Pipeline _context;
// api is public but ctor cannot be invoked by external caller
internal PipelineWithSteps(Pipeline context) => _context = context;
// now Trigger is available only after something was pushed
public PipelineWithSteps Trigger()
{
foreach(var step in _context._steps)
step();
Console.WriteLine();
return this;
}
// usually I don't repeat an initialization method;
// this could be done using the 'context'
// but would have to be refactored to return the existing 'PipelineWithSteps'
public PipelineWithSteps Push(Action step)
{
_context._steps.Add(step);
return this;
}
}
}
Usage:
var pipeline = new Pipeline();
pipeline.Push(() => Console.WriteLine("A"))
.Push(() => Console.WriteLine("B"))
.Trigger()
.Push(() => Console.WriteLine("C"))
.Trigger();
Output:
A
B
A
B
C
After hours ,i came up with this design:
public interface IBasePipelineRegister<T> where T:BaseResult
{
IStagePipeline<T> Push(StepBaseBusiness<T> step);
List<StepBaseBusiness<T>> Steps { get; set; }
}
public interface IBasePipelineTrigger<T> where T:BaseResult
{
void Trigger(T result);
}
public interface IStagePipeline<T>: IBasePipelineTrigger<T>,IBasePipelineRegister<T> where T:BaseResult
{
}
public class FlowBasePipeline<TResult> : IBasePipelineRegister<TResult> where TResult : BaseResult,new()
{
public List<StepBaseBusiness<TResult>> Steps { get ; set ; }
private IStagePipeline<TResult> _stagePipeline;
public BasePipeline()
{
this.Steps = new List<StepBaseBusiness<TResult>>();
this._stagePipeline = new StagePipeline<TResult>(this);
}
public IStagePipeline<TResult> Push(StepBaseBusiness<TResult> step)
{
Steps.Add(step);
return _stagePipeline;
}
}
As you see, BasePipeline just implements IBasePipelineRegister and Register method presents new StagePipeline class that is consist of current class plus trigger implementation.
public class StagePipeline<T>: IStagePipeline<T> where T:BaseResult
{
private readonly IBasePipelineRegister<T> pipelineRegister;
public List<StepBaseBusiness<T>> Steps { get; set; }
public StagePipeline(IBasePipelineRegister<T> pipelineRegister)
{
this.pipelineRegister = pipelineRegister;
Steps = pipelineRegister.Steps;
}
public IStagePipeline<T> Push(StepBaseBusiness<T> step)
{
return pipelineRegister.Push(step);
}
public void Trigger(T result)
{
foreach (var step in Steps)
{
result = step.Execute(result);
if (!result.IsSuccess)
{
break;
}
}
}
}
Now each method adds a new feature not replacing new one.
var pipeline=new FlowBasePipeline<MyStepResult>();
pipeline.Push(new MyStep1()).Push(new MyStep2()).Trigger();
I am not sure that this title is correct..Anyways I have a class that has a number of methods that control a stereo. Each method will send a command to a serial port. There are many models of stereos supported and each stereo may have a different command that needs to be sent.
For example model_A may need to send the command "VOLUP" to the serial port and "model_B" may need to send the command "GAINUP" to increase the volume. I want to have one method called IncreaseVolume like this:
public void IncreaseVolume()
{
serialPort.WriteLine(volumeCommand);
}
This method will be called from another class after setting the model of the radio. Now for two radios I could do this:
public class StereoControl
{
string volumeCommand;
string model_A_Volume_Command = "VOLUP";
string model_B_VOlume_Command = "GAINUP";
public void Set_Radio_Model(string model)
{
if (model == "modelA")
{
volumeCommand = model_A_Volume_Command;
}
else if (model == "modelB")
{
volumeCommand = model_B_Volume_Command;
}
}
public void IncreaseVolume(volumeCommand)
{
serialPort.WriteLine(volumeCommand);
}
}
So the main program will first set the model and then anytime the volume needs increasing it will just call the IncreaseVolume method.
The things is that there are potentially dozens of stereos and dozens of commands and I don't necessarily want all these in if then or case statements.
I thought of creating structures for each model containing the commands but then how do you select which structure to use in the methods?
I am sure there is a more elegant way to do this and am open to suggestions.
The first answer while usable, when we get 100+ commands and 200+ stereo's it will be a bit too difficult to handle. So here is another possibility but I do not know how to get the class reference available throughout the application.
public Class Model_A
{
string volumeCommand = "VOLUP";
}
public Class Model_B
{
string volumeCommand = "GAINUP";
}
public Class StereoControl
{
public void Set_Radio_Model(String model)
{
if (model == "model_a")
{
var _radio = new Model_A();
}
else if (model == "model_b")
{
var _radio = new Model_B();
}
}
public void IncreaseVolume()
{
serialPort.WriteLine(_radio.volumeCommand);
}
}
Of course the issue here is that the scope of _radio is only within the Set_Radio_Model. Is there a way to _radio usable everywhere?
Tom
The very basic way is to have Enum of stereos names and then implement it in OOP
(I hope people help to improve it) this is just depends on my opinion.
1- Define enum like:
public enum StereoBrand
{
Stero1 = 0,
Stereo2 = 1
}
2- Define an interface to enforce all stereos implement IncreaseVolume() like:
public interface IStereo
{
string VolumeCommand { get; }
string SteroeName { get; }
void IncreaseVolume();
}
by above interface each stereo should have a name as StereoName.
3- And then implement StereoController like :
public class SteroController : IStereo
{
public virtual string SteroeName
{
get
{
return string.Empty;
}
}
public virtual string VolumeCommand
{
get
{
return string.Empty;
}
}
public virtual void IncreaseVolume()
{
throw new NotImplementedException();
}
public static SteroController GenerateStereo(StereoBrand brand)
{
SteroController stereo = null;
switch (brand)
{
case StereoBrand.Stero1:
stereo = new Stereo1();
break;
case StereoBrand.Stereo2:
stereo = new Stereo2();
break;
}
return stereo;
}
}
Notes of Step3:
3.1- StereoController implement IStereo and change that prop and Increase method to Virtual that all Stereo can override them.
3.2- GenerateStereo which create related stereo by its StereoName
4- Suppose we have to implement Stereo classes here Stereo1 and Stereo2 like:
public class Stereo1 : SteroController
{
public override string SteroeName
{
get
{
return "Streo1";
}
}
public override string VolumeCommand
{
get
{
return "Command1";
}
}
public override void IncreaseVolume()
{
//Do anything with VolumCommand
}
public Stereo1()
{
}
}
public class Stereo2 : SteroController
{
public override string SteroeName
{
get
{
return "Streo2";
}
}
public override string VolumeCommand
{
get
{
return "Command2";
}
}
public override void IncreaseVolume()
{
//Do anything with VolumCommand2
}
public Stereo2()
{
}
}
5- The last step is using them like:
var stero = SteroController.GenerateStereo((StereoBrand)Enum.Parse(typeof(StereoBrand), "brandName"));
stero.IncreaseVolume();
Notes:
N1: This is better to implement GenerateStereo by reflection which means find all IStereo and make an instance by reflection.
N2: The another solution to avoid switch-case is using reflection to find related Stereo like:
public static SteroController GenerateStereo(StereoBrand brand)
{
SteroController stereo = null;
var type = typeof(IStereo);
var types = AppDomain.CurrentDomain.GetAssemblies()//Find all classes which implemented ISereo
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p)).ToList();
foreach(Type t in types)
{
var stereoNameProp = t.GetProperties().SingleOrDefault(p => p.Name == "StereoName");//Get stereo name prop
if (stereoNameProp != null && stereoNameProp.GetValue(t).ToString() == brand.ToString())//Check it with brand name
stereo =(SteroController)Activator.CreateInstance(type);//Make an instance
}
return stereo;
}
Hope it help and give you the clue.
I have interface that defines value and few operations:
public interface IValue<T>
{
T Value { get; }
void InteractionA(IValue<T> target);
void InteractionB(IValue<T> target);
bool Check(IValue<T> target);
}
Then i implement class based on that interface
public class DoubleValue : IValue<double>
{
public double Value { get; private set; }
public bool Check(IValue<double> target)
{
// ...
return false;
}
public void InteractionA(IValue<double> target)
{
// ...
}
public void InteractionB(IValue<double> target)
{
// ...
}
}
Now i want to make universal manipulator that operates on pool of values and uses generics (so i only write it once). Because of the way i want to use this class in the future it cannot be declared static. Moving generic type into methods also doesn't do any good.
The closest i could get is:
public class ValueManipulator<T>
{
public IEnumerable<IValue<T>> Pool { get; private set; }
public ValueManipulator(IEnumerable<IValue<T>> pool)
{
Pool = pool;
}
public void ManipulateA()
{
foreach (int i in Enumerable.Range(0, Pool.Count()))
{
IValue<T> firstValue = Pool.ElementAt(i);
foreach (IValue<T> secondValue in Pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
public void ManipulateB()
{
// ...
}
}
Main problem with this ValueManipulator class is that i need to know T of IValue used in DoubleValue (in this case double). So it looks like this:
static void Main(string[] args)
{
ValueManipulator<double> doubleManipulator = new ValueManipulator<double>();
doubleManipulator.Manipulate(ProvideDoubles());
}
private static IEnumerable<DoubleValue> ProvideDoubles()
{
yield return new DoubleValue();
yield return new DoubleValue();
yield return new DoubleValue();
}
How do i make ValueManipulator so user does not need to know what type was used in value implementation?
Well, if your ValueManipulator<T> has no state, as appears to be your case according to your code snippets, then simply make the methods generic instead of the class, that way you can leverage type inference.
public class ValueManipulator
{
public void Manipulate<T>(IEnumerable<IValue<T>> pool)
{
foreach (int i in Enumerable.Range(0, pool.Count()))
{
IValue<T> firstValue = pool.ElementAt(i);
foreach (IValue<T> secondValue in pool.Skip(i))
{
if (firstValue.Check(secondValue))
firstValue.InteractionA(secondValue);
else
firstValue.InteractionB(secondValue);
}
}
}
}
Now you can simply do:
ValueManipulator myManipulator = new ValueManipulator();
myManipulator.Manipulate(ProvideDoubles()); //type inference will figure out T is double
If this is a valid solution then consider making ValueManipulator a static class:
ValueManipulator.Manipulate(ProvideDoubles());
P.D. Please follow advice in commentaries and change ValueType to some other name thats less confusing.
UPDATE After your latest edit to your question, where you clearly state that ValueManipulator<T> does have state, the solution seems to be implementing a static factory class:
public static class ValueManipulator
{
public static ValueManipulator<T> Create<T>(IEnumerable<IValue<T>> pool)
=> new ValueManipulator<T>(pool);
}
public class ValueManipulator<T> { ... }
And again you let type inference do its job:
var doubleManipulator = ValueManipulator.Create(ProvideDoubles());
I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}
Suppose I have a base class named Visitor, and it has 2 subclass Subscriber and NonSubscriber.
At first a visitor is start off from a NonSubscriber, i.e.
NonSubscriber mary = new NonSubscriber();
Then later on this "mary" subscribed to some services, and I want to change the type of "mary" to Subscriber.
What is the conventional way to do that?
can't do that. sorry. C# is not a dynamic language.
You will have to create a new mary = new Subscriber(); and copy all relevant properties.
But a better approach might be to model it differently: Give Visitor a list of subscriptions. An empty list means a NonSubscriber.
You cant do this type of conversion.
What you should do is treat mary as a visitor, and when time arrives, create a new instance of "subscriber":
Visitor mary = new NonSubscriber();
// Do some Visitor operations
...
// Now mary is a Subscriber
mary = new Subscriber();
You could use the GOF design patterns State or Strategy to model such an behaviour. Using these patterns, it seems during runtime as if the class of the objects has been changed.
It seems that you have some design problems. I think that it would be better to redesign your code like:
class Visitor
{
private bool isSubscriber = false;
public bool IsSubscriber
{
get { return isSubscriber; }
}
public void Subscribe()
{
// do some subscribing stuff
isSubscriber = true;
}
public void Unsubscribe()
{
// do some unsubscribing stuff
isSubscriber = false;
}
}
You cannot change the type of a variable at runtime. You need to create a new instance.
mary = new Subscriber();
Create a Subscriber constructor that takes a NonSubscriber object as a parameter, or create a method on the NonSubscriber object that returns a Subscriber to save you having to writer the mappping code in multiple places.
It seems like you are encoding information incorrectly into your class hierarchy. It would make more sense to use a different pattern than sub classing here. For example, use only one class (visitor, or perhaps you could name it potential subscriber, whatever seems appropriate) and encode information on the services the object is subscribed to, moving the dynamically changing behavior behind a "Strategy" pattern or some such. There's very little detail in your example, but one thing you could do in C# is to make a "subscriber" property which would change the behavior of the object when the state of the property was changed.
Here's a contrived somewhat related example:
class Price
{
private int priceInCents;
private bool displayCents;
private Func<string> displayFunction;
public Price(int dollars, int cents)
{
priceInCents = dollars*100 + cents;
DisplayCents = true;
}
public bool DisplayCents
{
get { return displayCents; }
set
{
displayCents = value;
if (displayCents)
{
this.displayFunction = () => String.Format("{0}.{1}", priceInCents / 100, priceInCents % 100);
}
else
{
this.displayFunction = () => (priceInCents / 100).ToString();
}
}
}
public string ToString()
{
return this.displayFunction();
}
}
public class User
{
public Subscription Subscription { get; set; }
public void HandleSubscription()
{
Subscription.Method();
}
}
public abstract class SubscriptionType
{
public abstract void Method();
}
public class NoSubscription : SubscriptionType
{
public override void Method()
{
// Do stuff for non subscribers
}
}
public class ServiceSubscription : SubscriptionType
{
public override void Method()
{
// Do stuff for service subscribers
}
}
public class Service2Subscription : SubscriptionType
{
public override void Method()
{
// Do stuff for service2 subscribers
}
}
Think the code explains my answer :)
Adding to the other answers and your comment, you indeed can use the state pattern for your purpose, it would go something like this:
public class MyProgram
{
public void Run()
{
Visitor v = new Visitor("Mary");
Debug.Assert(v.SubscriptionLinkText == "Join now");
v.IsSubscribed = true;
Debug.Assert(v.SubscriptionLinkText == "Today's special");
v.IsSubscribed = false;
Debug.Assert(v.SubscriptionLinkText == "Join now");
}
}
public class Visitor
{
public string Name { get; set; }
private bool _isSubscribed;
public bool IsSubscribed
{
get { return this._isSubscribed; }
set
{
if (value != this._isSubscribed)
{
this._isSubscribed = value;
this.OnSubscriptionChanged();
}
}
}
private SubscriptionBase _subscription;
public string SubscriptionLinkText
{
get { return this._subscription.LinkText; }
}
public Visitor(string name)
{
this.Name = name;
this._isSubscribed = false;
this.OnSubscriptionChanged();
}
private void OnSubscriptionChanged()
{
// Consider also defining an event and raising it here
this._subscription =
SubscriptionBase.GetSubscription(this.IsSubscribed);
}
}
abstract public class SubscriptionBase
{
// Factory method to get instance
static public SubscriptionBase GetSubscription(bool isSubscribed)
{
return isSubscribed ?
new Subscription() as SubscriptionBase
: new NoSubscription() as SubscriptionBase;
}
abstract public string LinkText { get; }
}
public class Subscription : SubscriptionBase
{
public override string LinkText
{
get { return "Today's Special"; }
}
}
public class NoSubscription : SubscriptionBase
{
public override string LinkText
{
get { return "Join now"; }
}
}