I am building a game where several methods are chained to other and need to called behind the scenes. For example, when a soldier needs to leave the castle, the gate needs to be opened and then closed as soon as he leaves:
public void MoveTheGate(bool openTheGate)
{
if (openTheGate)
{
// code for: open the gate
}
else
{
// code for: close the gate
}
}
public void GetOutOfTheCastle()
{
MoveTheGate(true);
// code for: get out of the castle
MoveTheGate(false);
}
The same is true for when a messenger from another kingdom reaches the castle, the MoveTheGate() method has to be called both in the beginning and in the end of the messenger's entrance to the castle.
Is there a more delicate way to achieve this?
you could do
OpenGate(()=>
{ stuff to do with gate open }
);
where OpenGate is
public void OpenGate(Action action)
{
try
{
MoveTheGate(true);
action();
}
finally
{
MoveTheGate(false);
}
}
This may be total overkill, but you could always implement IDisposable then use a using block. That's a nice way to "make sure" it happens.
If you set up a class that called some given action on dispose,
public class DelegateDisposable : IDisposable
{
private readonly Action action;
public DelegateDisposable(Action action)
{
this.action = action;
}
public void Dispose()
{
if(this.action != null)
{
this.action();
}
}
}
Then you could use it like this:
private IDisposable OpenGate()
{
MoveTheGate(true);
return new DelegateDisposable(() => MoveTheGate(false));
}
And use it like this:
public void GetOutOfTheCastle()
{
using (OpenGate())
{
// code for: get out of the castle
}
}
A nice advantage of this approach is that it doesn't mess with your callstack, although again, it does have some overhead. But if you brought DelegateDisposable into some utility class, it could probably be useful for something else as well.
I would be impartial to an inheritance pattern that forces you to perform actions within the context of a base, inherited abstract class. The reason I believe this is preferable is because it allows you to easily encapsulate your Gate opening and closing and does not expose either the conditions for that to occur or that functionality outside of an inherited scenario.
public void Main()
{
var x = new InheritedAction();
}
public abstract class BaseGateAction
{
public void PerformBaseAction(Action actionToPerformWhileGateIsOpen)
{
Open();
actionToPerformWhileGateIsOpen();
Close();
}
private void Open()
{
Console.WriteLine("Gate has been opened");
}
private void Close()
{
Console.WriteLine("Gate has been closed");
}
}
public class InheritedAction : BaseGateAction
{
public InheritedAction()
{
PerformBaseAction(() =>
Console.WriteLine("Attack the dragon while the gate is open"));
PerformBaseAction(() =>
{
Console.WriteLine("Attack the dragon while the gate is open");
Console.WriteLine("The dragon is victorious and you have been devoured");
});
}
}
This code sample outputs the following for both PerformBaseAction method calls respectively:
Gate has been opened
Attack the dragon while the gate is open
Gate has been closed
Gate has been opened
Attack the dragon while the gate is open
The dragon is victorious and you have been devoured
Gate has been closed
This would allow for not only better code reuse, but far more encapsulated logic. You could always add additional exposed methods that take pre-conditions or post-conditions that would affect whether or not you could open the gate.
public abstract class BaseGateAction
{
....
public void PerformBaseActionWithPrecondition(Func<bool> precondition, Action actionToPerformWhileGateIsOpen)
{
if (precondition())
{
PerformBaseAction(actionToPerformWhileGateIsOpen);
}
else
{
Console.WriteLine("The gate could not be opened!");
}
}
...
}
This could be called as follows:
PerformBaseActionWithPrecondition<bool>(
() => true == false,
() => Console.WriteLine("Attack!")
);
And would output:
The gate could not be opened!
Related
suppose we have this scenario :
a class that you are not allowed to modify anything in it :
public class ForbiddenClass_A
{
public void TheMethod()
{
//do stuff
}
}
and another read only class that calls a method from the previous class:
public class ForbiddenClass_B
{
ForbiddenClass_A fc_a;
void Update()
{
//some logic that if true it will call :
fc_a.TheMethod();
}
}
Now you have your class, that you do anything to it, and from it you want to know if TheMethod() :
public class MyClass
{
//call this when TheMethod() from ForbiddenClass_A is called.
public void TheMethod_Catcher()
{
}
}
Thank you!
Is there a way to catch a method call without subscribing it to any
sort of Events?
Decoupled messaging is probably where you want to be, event aggregator or any other pub sub method messaging system. Although you still have to subscribe to something, the participants need not know about each other allowing you to make the methods private.
Unity, MvvmLight both have these sorts of messaging systems, however they are truly dime-a-dozen, there are plenty
Example of how this might work
public CreateUserForm()
{
InitializeComponent();
EventPublisher.Instance.Subscribe<NewUserCreated>
(n => listBoxUsers.Items.Add(n.User.Name));
}
...
// some other class
private void Update()
{
var user = new User()
{
Name = textBoxUserName.Text,
Password = textBoxPassword.Text,
Email = textBoxEmail.Text
};
EventPublisher.Instance.Publish(new NewUserRequested(user));
}
Update
There are injection techniques if you are interest for .net
Dynamically replace the contents of a C# method?
Suppose I have various arbitrary sections of code to run, but before each section, I have to run a Start() method and then after each section I need to run a Complete() method. However, if an exception is thrown in the code section, I want to run a Fail(string message) method instead of Complete(). Is there a design pattern that elegantly encapsulates this to make it neat and easily repeatable?
For example, let's say I have a type called Thing that contains a Start() method that adds a row to a logging db table to reflect that a task is in progress, a Complete() method that changes that row to reflect that the task finished and a Fail(string message) method that changes the row to reflect that the task failed. These are just examples though, they could be doing any set-up and tidy up type tasks.
The naive implementation might be simply to call those methods manually:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
But if I'm going to have to repeat this in a lot of different places, it ends up creating quite a lot of duplication and it might be easy to forget to call Complete or mess this up in some subtle way.
In C#, there's the using pattern, which provides a good way of encapsulating most of this. For example, if my Thing type looked like this:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
My DoStuff() method could now be simplified to this:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Which is much nicer. But it doesn't allow me to call Fail instead of Complete if an exception is thrown because (I think!) the Dispose method is essentially called in a Finally block.
I have thought of having a try/catch inside the using block and then setting a thing.HasFailed flag inside the catch block and then using that in the Dispose method to decide whether to Complete or Fail. But that seems a bit fiddly and I'd like the consumer of Thing to have to do as little as possible to make it work correctly.
So is there a design pattern that encapsulates what I want to do and avoids the need to manually write a try\catch each time?
You could have a Thing like this:
public class Thing
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}
public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}
}
}
And Use it like this:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);
The pattern is called "template method". You can find your implementation under the title "aspect oriented programming".
(https://msdn.microsoft.com/en-us/library/aa288717(v=vs.71).aspx)
Using Delegates.
public class Thing : IDisposable
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string _szMessage) {/* fail */}
public delegate void ProcessClientStuff();
private ProcessClientStuff m_delegateClientStuff;
public Thing(ProcessClientStuff _delegateClientStuff) {m_delegateClientStuff = _delegateClientStuff}
public void Dostuff()
{
Start();
try
{
m_delegateClientStuff();
Complete();
}
catch(Exception e)
{
Fail(e.Message);
}
}
}
void ClientStuff()
{
Console.WriteLine("Hello");
}
Thing oClientStuffProcessor = new Thing(ClientStuff);
oClientStuffProcessor.Dostuff();
2 objects are in this project: Region and Area.
Both objects have a method called
void load();
This is what I want to to, not sure if it's possible:
Invoke the same Detail function with similar implementation depending on which object called the function.
The Detail function will do something like this:
void Detail(parameter)
{
object_name.load();
}
I didn't want to write 2 overloaded functions for the each object because then I would have 2 functions with nearly identical implementations.
I have tried:
void Detail(string land)
{
if(land=="region")
{
Region land = new Region();
}
else if(land=="area")
{
Area land = new Area();
}
land.load();
}
But this doesn't work because land.load() will cause an error since the function cannot determine at definition whether land will be a Region or an Area object.
It sounds like you want an interface.
public interface IShape
{
void load();
}
Which both Region and Area would implement:
public class Region : IShape
{
public void load() { /* Region Implementation */ }
}
public class Area : IShape
{
public void load() { /* Area Implementation */ }
}
Your detail function now looks like this:
void Detail(IShape shape)
{
shape.load();
}
Some notes:
Interfaces define a contract without implementation. Your Detail function does not need to know whether it is an Area or a Region provided the class in question adheres to the contract that IShape defines, that is - it has a load() method.
Edit
Looking at your question more closely, it also looks like you want to implement a factory. So let's do that also.
public static class ShapeFactory
{
private static Dictionary<string, Func<IShape>> _shapes = new Dictionary<string, Func<IShape>>();
static ShapeFactory()
{
// Register some creators:
_shapes.Add("region", () => return new Region());
_shapes.Add("area", () => return new Area());
}
public static IShape Create(string shape)
{
return _shapes[shape]();
}
}
This allows your detail function to be rather simple:
void Detail(string shape)
{
ShapeFactory.Create(shape).load();
}
Error checking omitted for brevity. So what does this do? Well, a factory is - well - a factory. We create a dictionary (keyed by name), and whose value is a function that returns an IShape.. we can now dynamically create shapes by name and call the load method on it.
Edit 2
Given your comment that you cannot change what interfaces these classes implement, there's no reason we can't still obfuscate the load method (given that they both implement it). All we have to do is, once again utilise our interface again:
public interface IShapeWrapper
{
void load();
}
Note that our interface is still the same. What is different is the implementations:
public class RegionWrapper : IShapeWrapper
{
private Region _region;
public RegionWrapper()
{
_region = new Region();
}
public void load()
{
_region.load();
}
}
public class AreaWrapper : IShapeWrapper
{
private Area _area;
public AreaWrapper()
{
_area = new Area();
}
public void load()
{
_area.load();
}
}
The factory remains much the same, with the exception that it takes the wrapper classes rather than the Area/Region ones.
You might want to make the classes share an interface, e.g.
public interface ILoad { void Load(); }
public class Area : ILoad { }
public class Region : ILoad { }
void Detail(ILoad land)
{
land.Load();
}
Or maybe use dynamic, e.g.
void Detail(string landStr)
{
dynamic land;
if (landStr == "region")
{
land = new Region();
}
else
{
land = new Area();
}
land.load();
}
There are several ways of addressing this. A simple way would be giving both Area and Region classes an ILoadable interface to implement, like this:
interface ILoadable {
void load();
}
class Area : ILoadable {
public void load() {...}
}
class Region : ILoadable {
public void load() {...}
}
Now you can change your Detail method as follows:
void Detail(string land) {
ILoadable loadable;
if(land=="region") {
loadable = new Region();
} else if(land=="area") {
loadable = new Area();
} else {
throw new InvalidOperationException(land);
}
loadable.load();
}
If you would like to make Detail a generic function, you can get rid of the string land parameter, and pass the class directly:
void Detail<T>() where T : ILoadable, new() {
new T().load();
}
You can call this function like this:
Detail<Region>();
Detail<Area>();
Going the interface way is quite a possibility, or creating a full fledged Factory also, but it might be overkill depending on your need.
If you expect to have a lot more functions like load(), do it the way other have said, but if not, or if you cannot change what class they inherit like you stated, here is another way of doing it simply and quickly using dynamics:
void Detail(string land)
{
dynamic land = null;
if (land == "region")
{
land = new Region();
}
else if (land == "area")
{
land = new Area();
}
else
{
// Not what we expected
throw new ArgumentException("land: " + land);
}
try
{
land.load();
}
catch (RuntimeBinderException ex)
{
// .load() does not exist
}
}
So here is my setup and the comment shows what I wish to do:
class Process
{
void SomeMethod()
{
// Here I want to call Parent.MethodToCall()
}
}
class Controller
{
Process c = new Process();
void MethodToCall()
{
}
}
Now the Controller.MethodToCall() will be called many times throughout the lifecycle of the Process class.
It is only the parent method that needs to be called so I believe that using an event would be a bit wasteful as I will never be removing the handler and there would only be one invocation.
So the way I am currently using to get around this is like follows:
class Process
{
public Func<void> Method { get; set; }
void SomeMethod()
{
Method();
}
}
class Controller
{
Process c = new Process() { Method = MethodToCall }
void MethodToCall()
{
}
}
First off, the syntax might not be perfect, I quickly knocked it up in notepad.
My question: What is the best way to achieve what I want because what I am doing looks quite messy to be?...or am I thinking about this completely the wrong way in terms of design?
Essentially what I want to do is call a method in the Controller class without making it public, because if it is public, I could simply pass the Controller as a parameter to the Process.
class Child
{
Parent parent=null;
public Child(Parent p)
{
parent=p;
}
void SomeMethod()
{
parent.MethodToCall();
}
}
This should be a good example of how to do that
class Child : Parent
{
private void SomeMethod()
{
base.MethodToCall();
}
}
class Parent
{
Child c = new Child();
protected void MethodToCall()
{
c.MethodToCall();//not sure if you are wanting to call c.MethodToCall();
}
}
Well, in OOP terms the correct answer would be the following:
class Child : Parent
{
void SomeMethod()
{
base.MethodToCall();
}
}
class Parent
{
protected void MethodToCall()
{
// protected methods are accesible from
// descendants and private from outside
}
}
But you can always avoid inheritance, using aggregation
What you are doing is essentially rolling your own events. Internally, event handlers are just delegates attached to the event, with the one difference that only the owner of the event can raise it.
Maybe overloading a method is not exactly what is necessary but this is the best i could come up with.
I have a class:
public class Worker {
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
}
public void ProcessJob()
{
if(jobType.Equals("Pizza") MakePizza();
else if (jobType.Equals("Burger") MakeBurger();
}
private void MakePizza()
{
// make pizza
}
private void MakeBurger()
{
// make burger
}
}
The above is just an example of illustration. When the class is constructed, it is constructed with a specific job type, and that won't change. However it may need to perform millions of jobs, always of the same type. The ProcessJob() will be called all the time, but the caller won't know what type of worker this is. I would like to avoid running the if check every single time, there has to be a way to do that check only once and prep it.
In my case, making child classes (pizza worker, burger worker, etc.) is not an option, as in my real case, the class is large and there is only one tiny difference. Changing it will impact the whole architecture so it needs to be avoided.
Create an abstract base class, which contains common things a worker can do. Then declare derived classes for specialized workers.
public abstract class Worker
{
public abstract void ProcessJob();
}
public class PizzaWorker : Worker
{
public override void ProcessJob()
{
// Make pizza
}
}
public class BurgerWorker : Worker
{
public override void ProcessJob()
{
// Make burger
}
}
Now you can create workers of different types and let them do their job:
var workers = new List<Worker>();
workers.Add(new PizzaWorker());
workers.Add(new BurgerWorker());
foreach (Worker worker in workers) {
woker.ProcessJob();
}
This will automatically call the right implementation of ProcessJob for each type of worker.
Note: If-else-if cascades and switch statements are often an indication that the code works in a procedural rather than object-oriented way. Refactor it to be object-oriented!
You could use a delegate created when the object is constructed, this way the dispatch is done automatically:
public class Worker
{
private delegate void MakeSomething();
private MakeSomething makeWhat;
private string jobType;
public Worker(string jt)
{
this.jobType = jt;
switch (jt)
{
case "Pizza":
makeWhat = new MakeSomething(MakePizza);
break;
case "Burger":
makeWhat = new MakeSomething(MakeBurger);
break;
default:
throw new ArgumentException();
}
}
public void ProcessJob()
{
makeWhat();
}
private void MakePizza()
{
//make pizza
}
private void MakeBurger()
{
//make burger
}
}
I would still recommend to use sub classes. If you cannot inherit from Worker then create new class hierarchy that is used inside the worker. This way anyone using Worker class doesn't have to know that there are sub classes. If you really really hate sub classes or you have some other reason you don't want them you can use dictionary. It contains job type as key and Action as the method it calls. If you need more jobs just create the private method and register it in the RegisterWorkers method.
private Dictionary<string, Action> actions = new Dictionary<string, Action>();
public Worker(string jt)
{
this.jobType = jt;
this.RegisterWorkers();
}
private void RegisterWorkers
{
this.actions["Pizza"] = this.MakePizza;
this.actions["Burger"] = this.MakeBurger;
}
public void ProcessJob()
{
var action = this.actions[this.jobType];
action();
}
No, I don't think it should be avoided. Any common functionality should go in a base class. I think you need a static factory method, that returns a child class based on the string parameter.
public abstract class Worker {
public virtual void ProcessJob();
public static Worker GetWorker(string jobType) {
if(jobType.Equals("Pizza")
return new PizzaWorker();
else if (jobType.Equals("Burger")
return new BurgerWorker();
else
throw new ArgumentException();
}
// Other common functionality
protected int getFoo() {
return 42;
}
}
public class PizzaWorker : Worker {
public override void ProcessJob() {
// Make pizza
int y = getFoo() / 2;
}
}
public class BurgerWorker : Worker {
public override void ProcessJob() {
// Make burger
int x = getFoo();
}
}
So to use this:
Worker w = Worker.GetWorker("Pizza");
w.ProcessJob(); // A pizza is made.
This is exactly why there are patterns: Command, Strategy, Decorator.
I believe the command pattern is what you are looking for. First you have a basic 'command' template:
public interface IJob {
void ProcessJob();
}
Different jobs would then be performed as follows:
public class MakePizza : IJob {
// implement the interface
public void ProcessJob() {
// make a pizza
}
}
Now, you could have a JobFactory as follows:
public static class JobFactory {
public static IJob GetJob(string jobType) {
if(jobType.Equals("Pizza"){
return new MakePizza();
} else (jobType.Equals("Burger") {
return new MakeBurger();
}
// to add jobs, extend this if-else-if or convert to switch-case
}
}
Worker can now look like this:
public class Worker {
private IJob job;
public Worker(string jt) {
job = JobFactory.GetJob(jt);
}
public void ProcessJob() {
job.ProcessJob();
}
}
If you don't have access to code to make these changes, then another pattern you may want to look into is the Adapter.
You're talking about basic inheritance here. There are a couple of ways that you could do this.
Make a Base Class that is
public class Job
{
virtual void ProcessJob();
}
Then a MakePizza class
public class MakePizza : Job
{
public void ProcessJob()
{
//make Pizza
}
}
Then in your worker class instead of having a JobType as a string which will lead to all kinds of potential bugs.
public class Worker{
private Job jobType;
public Worker(Job jt){
this.jobType = jt;
}
public void ProcessJob()
{
Job.ProcessJob();
}
}
If you have to pass through a string you could simply load up the JobType through reflection, throwing a error if the type doesn't exist.
having to change other classes means you need to change code, not that you need to change architecture. the best answer is just to change the code. in the long term, the maintenance burden of having to write this in a less-than-ideal fashion will cost you more than just changing the code. use inheritance and bite the bullet on making the change now. if you have iterators that will have problems with dealing with subtypes, your iterators are doing more than being iterators, and you are better off fixing that than going forward with them. if the other classes care about what subtype of worker they are dealing with, that's a problem in and of itself that you should fix. ultimately, the dependent code should not care which type of worker it is. that's really what you are after anyway. the instance of a type that has work as its base type is still a worker and that is all the class using a worker should care about.