views:

409

answers:

7

Currently I am trying to implement a system or a way to create types but also get the type name when created.

So say I have actions like these, that can be created by the user of the app:

Blur
Contrast
Sharpen
Diffuse
Invert
...

So how should I extract their name when they are created through the UI. So say you have seperate UI buttons for each. Each time you create one of these, they will have to be named Blur01, Blur02, ... These objects will be created in millions.

So currently they have .Name property that has to be set on creation. But also I don't want to duplicate the code to set the names, inside each class.

What design pattern should I use for this?

A: 

FlyWeight?

Steve B.
Thanks, interesting but for my case, each object will be unique and not share anything between themselves unless I am missing something.
Joan Venge
A: 

Your best bet is to create a property (or function, if you prefer) in the base class that's virtual and provides a sort of base name. Something like..

public virtual string BaseName
{
    get { return GetType().Name; }
}

Your .Name property could stay the same, or change to something like .NameSuffix, and you could combine BaseName and NameSuffix to form a complete name.

In the end, though, this probably isn't the best way to go about this. What is the purpose of naming these objects/actions? It looks to me like you're using a command pattern in image manipulation and you're either setting up a chain of actions to perform, or want to keep a chain of actions to undo. Such a system would be better suited to a linked list structure, which you could display (if necessary) in some sort of graph, showing the action (likely the name of the class, or the BaseName as defined above) and the series in which they would be executed.

As far as your need to use the name to instantiate the objects, I'm not quite sure why. If this is truly necessary, your only two options would be a factory pattern or using reflection on either the name of the class or a custom attribute value (which could also be used for providing the name, if desired). However, if you're going to be instantiating them "in the millions" stay away from reflection.

I guess this is a roundabout way of saying it all depends on how this needs to work. You'll have to provide more concrete and comprehensive information for a correspondingly concrete and comprehensive answer.

Adam Robinson
Thanks Adam. Basically I am not doing this for undo or action history. It's actually working on images, etc in a hierarchical way so like this:http://numerof.com/blog/wp-content/uploads/2007/12/combustion_2008.jpgSo these will be objects where you change the properties of each instance.
Joan Venge
Also GetType isn't using reflection, right?
Joan Venge
This will return the base type name, unless it's overriden in each derived type, in which case you might as well put explicit type name const string fields in each derived type
Charles Bretana
Basically what I mean is, I am not gonna use the name to instantiate, but to name the object so it's unique. So in the scripting language of the app, you could do stuff like $Blur01 to access it.
Joan Venge
+2  A: 

If you want each type to get it's own, unique incrementers, you're going to have duplicated code. You could avoid this with reflection by saving a static dictionary in a base class with Type and int... something like:

private static Dictionary<Type,int> nameSuffixCounters =
     new Dictionary<Type,int>();

public string CreateName()
{
    Type type = this.GetType();
    return string.Format("{0}{1}",type.Name, this.GetNextAndIncrement(type));
}

private int GetNextAndIncrement(Type type)
{
    int current;
    if (!this.nameSuffixCounters.TryGetValue(type, out current))
    {
        current = 0;
    }
    nameSuffixCounters[type] = ++current;
    return current;
}

Something like this would get rid of the duplicated code, but it's adding some complexity in using reflection in the base class...

Reed Copsey
+2  A: 

Command Pattern?

Using this pattern would have the advantage of laying the groundwork for undo/redo capability, which it looks like you might need at some point.

Briefly, you could create a interface called "Command" from which subclasses called "Blur", "Sharpen", etc would be derived. Command would define an execute() method that would be implemented by your subclasses as needed:

public interface Command
{
  public void execute();

  public String getName();
}

public class Blur implements Command
{
  // ...

  public Blur(String name)
  {
    // ...
  }

  //...

  public void execute()
  {
    // execute the blur command
  }
}

Many UI toolkits come with support for this pattern - for example Swing. So you may not need to do much to get it working.

Rich Apodaca
Thanks, how would you undo using this system?
Joan Venge
If Blur is to be used with a Drawing, for example, you might define Command.execute(Drawing drawing) and Command.revert(Drawing drawing). Each of your Commands would do and undo something different to the Drawing.
Rich Apodaca
How does this solve the problem of naming the created instances? You're just passing it to the .ctor from what I see....
Mark Brackett
A: 

I'm afraid there's no way to do this in one single place.. You will have to explicitly 'type' the class (type) name in each class definition. The reason is that any reflection in the base class will return the base class type, not the concrete type... unless you override the method in each derived class, in which case you might as well hard code the type name as a string const (to avoid the reflection hit) ...

So, what about

public const string TypeName = "MYTypeName";
Charles Bretana
A: 

If it doesn't have to be human readable I would use a GUID as the name of the object and have a base field to indicated the base action that it was created from. Each object can be uniquely identified as (Base Name)-(ID). You could have a human readable Description field but that not used for look up. If you do need to display a GUID a trick that I use is convert from Base 16 to Base 34. Basically from 0123456789ABCDEF to 0123456789ABCDEFGHJKLMNPQRSTUVWXZY. This produces a much shorter string that is easier to display and type in.

RS Conley
Can you please give me an example for this?
Joan Venge
+1  A: 

I'm not sure why (most) of the answers mention reflection - good ol' polymorphism works just fine for this. Getting the runtime type name is easy - it's just this.GetType().Name.

The only somewhat tricky part is maintaining unique counters per class. That's been discussed before on SO - but I can't find a link ATM. But, the bottom line, is that you can either (ab)use generics or maintain a Dictionary<Type, int> to keep track.

The generic version works because each different type parameter creates a different generic class - so they each have different static counters:

abstract class Command<T> where T : Command<T> {
   private static int counter = 1;
   private static object syncLock = new object();

   protected Command() {
      lock (syncLock) {
         _name = this.GetType().Name + counter++.ToString();
      }
   }

   public string Name { get { return _name; } }
   private string _name;
}

class Blur : Command<Blur> { }

class Sharpen : Command<Sharpen> { }

There's no need to override anything in the derived classes, but you do have to make sure your inherited Command<T> is correct - or you'll share counters. I also used a lock to synchronize access to counter - assuming you'll create instances from more than 1 thread.

If you don't like the generic version, then a Dictionary<Type, int> works just as well.

abstract class Command {
   private static Dictionary<Type, int> counter = new Dictionary<Type, int>();
   private static object syncLock = new object();

   protected Command() {
      Type t = this.GetType();
      lock (syncLock) {
         if (!counter.ContainsKey(t)) {
            counter.Add(t, 0);
         }
         _name = t.Name + counter[t]++.ToString();
      }
   }

   public string Name { get { return _name; } }
   private string _name;
}

class Blur : Command { }
class Sharpen : Command { }

Since you'll be creating "millions" of each, I'd probably profile both and check memory usage. I don't particularly care for the generic approach - since it's easy to screw up and pass the wrong type parameter - but I suspect it's memory usage is a bit better. Also, if you're going to create > int.MaxValue, you'll have to worry about overflow.

All that being said, I'm not sure why you wouldn't just maintain an index addressable collection and reference them by index - like Blur[0]?

Mark Brackett
Hi Mark, thanks for the reply. I can and possibly use Blur[0], but this naming was on the user side: So think of it as what the user will see in the UI, so like hey I have a new Blur, and it's called Blur01. Internally I haven't really decided on how to design this entirely, plan to think about that soon. Thanks.
Joan Venge