I have several different objects, but I have to do similar actions with them.
What is better to use:
1. Several methods and use these objects as type parameters.
2. Use one method which gets System.Object as parameter. And inside this method I will check type of parameter and do some action.
For example I should send notifications for some actions. I have objects Action1, Action2, Action3...ActionN, which contain details of these actions. Should I use:
public void SendNotificationForAction1(Action1 action) {}
public void SendNotificationForAction2(Action2 action) {}
public void SendNotificationForActionN(ActionN action) {}
or
public void SendNotification(Object action)
{
//here I will check type of action and do something
}
I guess it depends:
Is the code to send notifications more or less the same? Then I would opt for:
public void SendNotificationFor<T>(T action) {}
otherwise I'd probably choose to overload the method:
public void SendNotification(Action1 action) {}
public void SendNotification(Action2 action) {}
public void SendNotification(ActionN action) {}
The first one is type-safe, the second one is not. Therefore, if I 've to choose between those two options, I'd chose the first one.
On the other hand, isn't it possible to go with an entirely different approach ?
Where you have one base-class or interface Action, where other classes derive from ?
The interface or base-class could have a 'GetDetailsForNotification' method, which you implement in the implementors, and you can use that method in the SendNotificationForAction method.
something like this, but, offcourse, I do not know if this is viable in your context:
interface IAction
{
string GetDetailsForNotification();
}
public class Action : IAction{
public string GetDetailsForNotification()
{
return "details from Action";
}
}
public class Action2 : IAction{
public string GetDetailsForNotification()
{
return "details from Action2";
}
}
public void SendNotificationForAction(IAction action) {
var details = action.GetDetailsForNotification();
...
}
The Strategy Pattern may fit here too:
private interface INotificationStrategy<T> // or non-generic with object
{
void SendNotification(T action);
}
public class StringNotificationStrategy : INotificationStrategy<string>
{
public void SendNotification(string action)
{
throw new NotImplementedException();
}
}
A Factory could provide you the correct implementation, and you could provide further implementations without breaking existing interfaces...
I would go with the first approach.
It entails creating more methods, and possibly a bit more code, but I believe it to be much easier to use and typesafe.
Your second approach doesn't allow me to know in compile time what kind of Object the method is expecting without reading the code (imagine you distribute this code to be used as a library), and if I pass the wrong method, the only thing you can do is to make it fail in runtime - not great.
You should try to keep the method as generic as possible.
The SendNotification method could be built like this:
public void SendNotification<T>(T action) where T : SpecialAction {
}
The class/interface SpecialAction can then have methods that are different between the actions. For instance:
[abstract class] [interface] SpecialAction {
public string GetName();
public bool CanDoX();
}
As guys said, it depends, but generally I prefer variation(below) of 2nd approach, cause of it's easier to extend in future(of course, if you need).
interface ISendNotificationHandler
{
Type ActionType { get; }
void SendNotification(object action)
}
class Action1SendNotificationHandler : ISendNotificationHandler
{
public Type ActionType {get{return typeof(Action1);}}
public void SendNotification(object action)
{
Action1 a = (Action1)action;
// TODO: send notification
}
}
// your method originally posted
public void SendNotification(Object action)
{
var handlers = new ISendNotificationHandler[]{ new Action1SendNotificationHandler(), /* etc*/}
//
var handler = handlers.FirstOrDefault(h=>action.GetType().IsSubclassOf(h.ActionType))
if(handler != null)
{
handler.SendNotification(action);
}
else
{
throw new Exception("Handler not found for action " + action);
}
}
Have you considered using Observer Pattern
Wiki Link is here.
To keep it short, lets say you have subscribed to a news paper, when ever there is a new edition(event) of news paper, the subscriber will get notified and the new version is delivered.
here is my try :
Every ActionN class is derived from base Action :
class Action1: Action, INotify
{
public void override SendNotification() {...}
}
If some notifications have common implementation then have it in Action class.
Now in the class who sends notification do this :
class Sender
{
public void SendNotif(INotify actn)
{
actn.SendNotification();
}
}
And send proper object to SendNotif() method.
Related
I've got a design question.
I've got a static class used in some old code that calls a static method to run some operation. If a certain condition is met, I want to call another method right after it.
I wanted to use the decorator pattern but I can't exactly return an instance of the static class if the condition is not met.
This is what's happening now.
var result = StaticClass.DoSomething(some parameters);
What I want is to write to a database right after that DoSomething is called if another variable is true and I didn't want to just pile on to the old code with conditionals so I'd rather delegate that to some other class. This is what I really want to do.
var result = StaticClassFactory(condition).DoSomething(some parameters);
Class1
void DoSomething(parameters) {
StaticClass.DoSomething()
}
Class2
void DoSomething(parameters) {
StaticClass.DoSomething();
DoSomethignElse();
}
Any suggestions?
What you can do is use an interface to represent the "doer":
public interface IDoer
{
void DoSomething(object parameters);
}
Then create the two classes:
public class DefaultDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
}
}
public class AugmentedDoer : IDoer
{
public void DoSomething(object parameters)
{
StaticClass.DoSomething(object parameters);
DoSomethingElse();
}
}
Then use a factory to return an instance that implements IDoer based on the condition:
public class DoerFactory
{
public IDoer GetDoer(object someCondition)
{
//Determine which instance to create and return it here
}
}
I used placeholders of type object for some things as no more information is available.
Is there a way to modify the behavior of a static method at runtime?
for example:
Say I have this class
public class Utility {
public static void DoSomething(string data){
//...
}
}
Is there a way to do something like this:
typeof(Utility).SetMethod("DoSomething", (data) => { /*Do something else...*/ });
Such that if you call Utility.DoSomething it executes the new code?
What you want to do is pass the behavior you want as another parameter into the function.
public static void DoSomething(string data, Action<string> operation)
{
operation(data);
}
This is an oversimplified example, of course. What you actually wind up doing in your own code is going to depend on what operation actually does.
If you're trying to modify the behavior of an existing, compiled, in-production method, and cannot overload or override the method in the usual ways, the only way I know of to do that is CIL Rewriting, possibly using an Aspect Weaver.
Sure.
public class Utility {
public static Action<String> _DoSomething;
public static void DoSomething(string data){
if (_DoSomething != null) {
_DoSomething();
return;
}
// default behavior here.
}
}
And to mask the default behavior:
Utility._DoSomething = (data) => { /* do something else */ };
I don't see why you wouldn't just create a new class that inherits from Utility and define a new function that does what you want.
public class Program
{
static void Main(string[] args)
{
if (true)
{
Utility.DoSomething("TEST");
} else
{
Util1.DoSomething("TEST");
}
}
}
public class Utility
{
public static void DoSomething(string data)
{
//Perform some action
}
}
abstract class Util1 : Utility
{
public static new void DoSomething(string data)
{
//Perform a different action
}
}
I think although it is possible to do this you should ask yourself: "Why do I need this functionality"? Usually a method stays as is, and does what it is supposed to do according to its interface which is given by its name and signature. So while you can add additional logic by adding an Action<T>-parameter to your signature you should ask yourself if this won´t break the contract of the interface and therefor what the method was designed for.
Having said this you should consider either overwrite your method if the functionality you need is some kind of "making the same things differently then the parent-class" or extend it by adding a dependency into your consuming class and add some methods to that class that extent the functionality provided by the contained class (see also favour composition over inheritance)
class MyClass {
Utility MyUtility;
void ExtraMethod() { /* ... */ }
}
EDIT: As you´re using a static method the opportunity on overwriting is obsolete. However IMO that sounds like a great design-flaw.
The following code is a valid C# construct that compile juste fine.
public class Weird : Weird.IWeird
{
private interface IWeird
{
}
}
What would be the possible uses of this?
Edit: This question is more specific that this one: "What is a private interface?". It shows that it's possible to implement a private interface from the parent type itself, which seems to be rather pointless. The only use I can think of would be a weird case of interface segregation where you would want to pass an instance of the parent class to a nested class instance as IWeird.
This is probably one of these situations in compiler development when prohibiting something has a higher cost than allowing it. Prohibiting this use would require writing and maintaining code to detect this situation, and report an error; if the feature works as-is, this is an additional work for the team, and it could be avoided. After all, perhaps someone with good imagination could figure out a way to use the feature.
As far as a useful example goes, one potential use is to make another implementation in the class, and use it as an alternative without exposing it to the users of the API:
public class Demo : Demo.Impl {
// Private interface
private interface Impl {
public bool IsValidState {get;}
void DoIt();
}
// Implementation for the error state
private class Error : Impl {
public bool IsValidState { get { return false; } }
public void DoIt() {
Console.WriteLine("Invalid state.");
}
}
private readonly string name;
// Implementation for the non-error state
public bool IsValidState { get { return true; } }
public void DoIt() {
Console.WriteLine("Hello, {0}", name);
}
// Constructor assigns impl depending on the parameter passed to it
private readonly Impl impl;
// Users are expected to use this method and property:
public bool IsValid {
get {
return impl.IsValidState;
}
}
public void SayHello() {
impl.DoIt();
}
// Constructor decides which impl to use
public Demo(string s) {
if (s == null) {
impl = new Error();
} else {
impl = this;
name = s;
}
}
}
As far as best practices go, this design is questionable at best. In particular, I would create a second nested class for the non-error implementation, rather than reusing the main class for that purpose. However, there is nothing terribly wrong with this design (apart from the fact that both IsValidState and DoIt are visible) so it was OK of the C# team to allow this use.
I have 2 cases wheter a method can be considered a Factory Design Pattern, this example is in C#, altought, can apply to other programming languages:
enum NinjaTypes {
Generic,
Katanna,
StarThrower,
Invisible,
Flyer
}
public class Ninja {
public string Name { get; set; }
public void jump() { ... }
public void kickAss() { ... }
}
public class KatannaNinja: Ninja {
public void useKatanna() { ... }
}
public class StarNinja: Ninja {
public void throwStar() { ... }
}
public class InvisibleNinja: Ninja {
public void becomeInvisible() {...}
public void becomeVisible() {...}
}
public class FlyNinja: Ninja {
public void fly() {...}
public void land() {...}
}
public class NinjaSchool {
// always return generic type
public Ninja StandardStudent() {...}
// may return other types
public Ninja SpecialityStudent(NinjaTypes WhichType) {...}
}
The method StandardStudent() always return a new object of the same type, the SpecialityStudent(...), may return new objects from different classes that share the same superclass / base type. Both methods are intentionally not virtual.
The question is, are both methods "Factory Design Pattern" ?
My guess is that SpecialityStudent(...) is, but StandardStudent() is not. If the second is not, can be considered another design pattern ?
I don't think that nor a FactoryMethod`nor AbstractFactory patterns forbid the user to use a parameter to specify a type to the creator method. Anyway you should consider at least 2 things in your design:
Factory methods are useful to keep the client unaware of the concrete type of the created object. From my point of view isn't wrong to specify explicitly the type of object to be created, but pay attention to not put too much knowledge on the client classes to be able to construct objects through the factory.
Both your factory methods return a Ninja object, but some of your ninjas extended class declare additional methods, which client is unaware of. If your client need to use those methods explicitly then maybe you have to make some consideration on your design.
I think this actually looks like an Anti-Pattern. There's really nothing to stop a consumer of this code to just instantiate the specialty ninjas directly. What benefit is there to using the Ninja School? I think the whole point of the Factory pattern is to encapsulate the process of instantiating an object so that you can hide the details from the consumer. Any time you make a change to the "creation" logic, it doesn't break anyone's code.
And it just looks like a bad idea to have all the types in an enum. I don't have a concrete reason to back up this claim other than, "it feels wrong".
After reviewing the Abstract Factory pattern, I can see how you could go about turning this into an Abstract Factory, but I don't see the benefit given the semantics of your objects. I think that if you want to have a Ninja factory, you'd have to make the individual constructors protected or internal, so they can't be called directly by consumer code
Both your methods can be seen as factories. But the second one is a little awkward to use:
var school = new NinjaSchool();
var ninja = school.SpecialtyStudent(NinjaTypes.Flyer);
// to fly you must cast
((FlyingNinja)ninja).Fly();
You've already asked for a flyer, so you shouldn't need to cast. A better option might be to eliminate the enum and ask for the exact ninja that you want:
var flyingNinja = school.FlyingStudent(); // you get a FlyingNinja
flyingNinja.Fly();
Another thing to consider in your design is this: what if you want an invisible ninja that can fly? Or a katana ninja that also throws stars? That will shake up your hierarchy and challenge your belief in inheritance.
It's almost a factory method. I would do something like:
enum NinjaTypes {
Generic, Katanna, StarThrower, Invisible, Flyer
}
class Ninja {
String Name;
void jump() {
}
void kickAss() {
}
void useKatanna() {
System.out.println("nothing happens");
}
void throwStar() {
System.out.println("nothing happens");
}
void becomeInvisible() {
System.out.println("nothing happens");
}
void becomeVisible() {
System.out.println("nothing happens");
}
void fly() {
System.out.println("nothing happens");
}
void land() {
System.out.println("nothing happens");
}
}
class StarThrowerNinja extends Ninja {
void throwStar() {
System.out.println("throwing star");
}
}
class NinjaSchool {
static Ninja create(NinjaTypes WhichType) {
switch (WhichType) {
case Generic:
return new Ninja();
case StarThrower:
return new StarThrowerNinja();
default:
return null;
}
}
}
public class Main {
public static void main(String[] args) {
Ninja generic=NinjaSchool.create(NinjaTypes.Generic);
generic.throwStar();
Ninja starThrower=NinjaSchool.create(NinjaTypes.StarThrower);
starThrower.throwStar();
}
}
What is the best way to implement polymorphic behavior in classes that I can't modify? I currently have some code like:
if(obj is ClassA) {
// ...
} else if(obj is ClassB) {
// ...
} else if ...
The obvious answer is to add a virtual method to the base class, but unfortunately the code is in a different assembly and I can't modify it. Is there a better way to handle this than the ugly and slow code above?
Hmmm... seems more suited to Adapter.
public interface ITheInterfaceYouNeed
{
void DoWhatYouWant();
}
public class MyA : ITheInterfaceYouNeed
{
protected ClassA _actualA;
public MyA( ClassA actualA )
{
_actualA = actualA;
}
public void DoWhatYouWant()
{
_actualA.DoWhatADoes();
}
}
public class MyB : ITheInterfaceYouNeed
{
protected ClassB _actualB;
public MyB( ClassB actualB )
{
_actualB = actualB;
}
public void DoWhatYouWant()
{
_actualB.DoWhatBDoes();
}
}
Seems like a lot of code, but it will make the client code a lot closer to what you want. Plus it'll give you a chance to think about what interface you're actually using.
Check out the Visitor pattern. This lets you come close to adding virtual methods to a class without changing the class. You need to use an extension method with a dynamic cast if the base class you're working with doesn't have a Visit method. Here's some sample code:
public class Main
{
public static void Example()
{
Base a = new GirlChild();
var v = new Visitor();
a.Visit(v);
}
}
static class Ext
{
public static void Visit(this object b, Visitor v)
{
((dynamic)v).Visit((dynamic)b);
}
}
public class Visitor
{
public void Visit(Base b)
{
throw new NotImplementedException();
}
public void Visit(BoyChild b)
{
Console.WriteLine("It's a boy!");
}
public void Visit(GirlChild g)
{
Console.WriteLine("It's a girl!");
}
}
//Below this line are the classes you don't have to change.
public class Base
{
}
public class BoyChild : Base
{
}
public class GirlChild : Base
{
}
I would say that the standard approach here is to wrap the class you want to "inherit" as a protected instance variable and then emulate all the non-private members (method/properties/events/etc.) of the wrapped class in your container class. You can then mark this class and its appropiate members as virtual so that you can use standard polymorphism features with it.
Here's an example of what I mean. ClosedClass is the class contained in the assembly whose code to which you have no access.
public virtual class WrapperClass : IClosedClassInterface1, IClosedClassInterface2
{
protected ClosedClass object;
public ClosedClass()
{
object = new ClosedClass();
}
public void Method1()
{
object.Method1();
}
public void Method2()
{
object.Method2();
}
}
If whatever assembly you are referencing were designed well, then all the types/members that you might ever want to access would be marked appropiately (abstract, virtual, sealed), but indeed this is unfortunately not the case (sometimes you can even experienced this issue with the Base Class Library). In my opinion, the wrapper class is the way to go here. It does have its benefits (even when the class from which you want to derive is inheritable), namely removing/changing the modifier of methods you don't want the user of your class to have access to. The ReadOnlyCollection<T> in the BCL is a pretty good example of this.
Take a look at the Decorator pattern. Noldorin actually explained it without giving the name of the pattern.
Decorator is the way of extending behavior without inheriting. The only thing I would change in Noldorin's code is the fact that the constructor should receive an instance of the object you are decorating.
Extension methods provide an easy way to add additional method signatures to existing classes. This requires the 3.5 framework.
Create a static utility class and add something like this:
public static void DoSomething(this ClassA obj, int param1, string param2)
{
//do something
}
Add a reference to the utility class on the page, and this method will appear as a member of ClassA. You can overload existing methods or create new ones this way.