Reputation: 119
I know my question is not perfectly asked but it was rather hard so I will show with an example: So I have a class AbstractHandler. I create it with a method from another class:
class AbstractManager
{
BinarySerializator binarySerializator; //just for the example
TextSerializator textSerializator;
public AbstractManager(BinarySerializator binarySerializator) {
this.binarySerializator = binarySerializator;
this.textSerializator = null;
}
public AbstractManager(TextSerializator textSerializator) {
this.textSerializator = textSerializator;
this.binarySerializator = null;
}
public AbstractHandler createHandler() {
if (this.binarySerializator != null) {
return new AbstractHandler<byte[]>(this.binarySerializator);
} else {
return new AbstractHandler<String>(this.textSerializator);
}
}
}
So this is how I create the AbstractHandler which again has the two constructors (one that takes a BinarySerializator and another for TextSerializator). Now here is the fun part: both Serializators have a method which is getSerializedType(Object object), the binary returns byte[] the text returns String. I want my method in the AbstractHandler to return either byte[] or String depending on the type of serializator I have:
public T createSerializable(Object object) {
if (binarySerializer != null) {
return (T) binarySerializer.getSerializedType(object);
}
if (textSerializer != null) {
return (T) textSerializer.getSerializedType(object);
}
}
My question is - is this the way to do it? Also is there a workaround with the two constructors and how am I supposed to deal with the two different AbstractHandlers, I know it's possible to be done with generics instead of havign two classes (one for String, one for byte[]). Thanks for taking your time to read this long post.
Upvotes: 1
Views: 618
Reputation: 1561
I have two solutions:
interface ISerializatorStategy
{
object GetSerializedType(object obj);
}
// If you want generic classes
interface ISerializatorStategy<T> : ISerializatorStategy
{
new T GetSerializedType(object obj);
}
// If you don't want generic classes
// you can inherit from the base interface and implement only its method
class TextSerializator : ISerializatorStategy<string>
{
public string GetSerializedType(object obj)
{
return "Hello World";
}
object ISerializatorStategy.GetSerializedType(object obj)
{
return GetSerializedType(obj);
}
}
class IntSerializator : ISerializatorStategy<int>
{
public int GetSerializedType(object obj)
{
return 42;
}
object ISerializatorStategy.GetSerializedType(object obj)
{
return GetSerializedType(obj);
}
}
class AbstractManager
{
protected ISerializatorStategy SerializatorStrategy { get; set; }
public AbstractManager(ISerializatorStategy serializatorStrategy)
{
SerializatorStrategy = serializatorStrategy;
}
public AbstractHandler CreateHandler()
{
return new AbstractHandler(SerializatorStrategy);
}
}
// If you want generic classes
class AbstractManager<T> : AbstractManager
{
// Note, if you allow this constructor,
// you could encounter runtime errors
public AbstractManager(ISerializatorStategy serializatorStrategy)
: base(serializatorStrategy)
{
}
public AbstractManager(ISerializatorStategy<T> serializatorStrategy)
: base(serializatorStrategy)
{
}
public new AbstractHandler<T> CreateHandler()
{
return new AbstractHandler<T>(SerializatorStrategy);
}
}
class AbstractHandler
{
private readonly ISerializatorStategy _serializatorStrategy;
public AbstractHandler(ISerializatorStategy serializatorStrategy)
{
_serializatorStrategy = serializatorStrategy;
}
public object CreateSerializable(object obj)
{
return _serializatorStrategy.GetSerializedType(obj);
}
public void GetSerializable<T>(object obj, out T serializebleObject)
{
serializebleObject = (T)_serializatorStrategy.GetSerializedType(obj);
}
}
// If you want generic classes
class AbstractHandler<T> : AbstractHandler
{
// Note, if you allow this constructor,
// you could encounter runtime errors
public AbstractHandler(ISerializatorStategy serializatorStrategy)
: base(serializatorStrategy)
{
}
public AbstractHandler(ISerializatorStategy<T> serializatorStrategy)
: base(serializatorStrategy)
{
}
public new T CreateSerializable(object obj)
{
return (T)base.CreateSerializable(obj);
}
}
class Program
{
static void Main(string[] args)
{
var textManager = new AbstractManager<string>(new TextSerializator());
var textHandler = textManager.CreateHandler();
string textResult = textHandler.CreateSerializable(null); // or AbstractHandler<string> as type
Console.WriteLine(textResult);
var intManager = new AbstractManager<int>(new IntSerializator());
var intHandler = intManager.CreateHandler(); // or AbstractHandler<int> as type
int intResult = intHandler.CreateSerializable(null);
Console.WriteLine(intResult);
Console.ReadKey();
}
}
class Program
{
static void Main(string[] args)
{
AbstractManager manager = new AbstractManager(new TextSerializator());
AbstractHandler handler = manager.createHandler();
string textResult;
handler.GetSerializable(null, out textResult);
Console.WriteLine(textResult);
manager = new AbstractManager(new IntSerializator());
handler = manager.createHandler();
int intResult;
handler.GetSerializable(null, out intResult);
Console.WriteLine(intResult);
Console.ReadKey();
}
}
Now, you shouldn't have troubles to apply this on your issue.
Upvotes: 1