I'm writing a C# application that reads in a source code file of language X, and populates a data structure with the classes, methods etc. that appear in the source file.
After that, using this data structure I just populated, I can call any of these three functions:
GenerateCS()
GenerateJava()
GenerateCPP()
Basically, it ports language X to either of those three languages.
My question is, how can I structure this such that I have one class GenerateCode which functions as a base class and the other generate functions derive from it?
I suppose the particular syntax details of each language would have to reside within the derived classes itself, but what stuff could I abstract to the superclass?
What about:
public enum Language
{
CS,
Java,
CPP
}
public class CS: BaseClass { }
public class Java: BaseClass { }
public class Cpp: BaseClass { }
public class BaseClass
{
public abstract BaseClass ConvertTo(Language lang);
}
or
public class BaseClass
{
public abstract FromClass(BaseClass class, Language lang);
}
I would recommend that you start with a structure like this:
public class MetaCode
{
private IList<Fields> fields;
private IList<Properties> properties;
private IList<Methods> methods;
public IList<Fields> Fields
{
get { return this.fields; }
}
public IList<Properties> Properties
{
get { return this.properties; }
}
public IList<Methods> Methods
{
get { return this.methods; }
}
// etc...
}
public interface ISourceReader
{
MetaCode ReadCode(string sourceCode);
}
public interface ISourceWriter
{
string WriteCode(MetaCode metaCode);
}
public class CodeConverter
{
private ISourceReader reader;
private ISourceWriter writer;
public CodeConverter(ISourceReader reader, ISourceWriter writer)
{
this.reader = reader;
this.writer = writer;
}
public string Convert(string sourceCode)
{
MetaCode metaCode = this.reader.ReadCode(sourceCode);
return this.writer.WriteCode(metaCode);
}
}
This is just pseudo-code, but you could probably make your interfaces follow the StreamReader/StreamWriter pattern that appears frequently in the .NET framework.
The interfaces allow neat extension points where you can add new source and destination programming languages to your application. The best thing about this approach is that the CodeConverter class knows nothing about the different programming languages that exist. New ones can be added or removed and it doesn't need to change. Other people can even create new language readers / writers and use them without touching your code / compiled assembly.
To be honest, thinking about this, I dont think there is much functionality that you can abstract out to a base class. The details of each language is so specific that a base class is difficult to do correctly. In any case, I'd always recommend starting out with the interfaces because then you can always create an implementation no matter how obscure / different a programming language is.
Perhaps you could create several "helper" base classes that contain some abstracted functionality for the different general styles of programming language there are:
public abstract class CLikeSourceReader : ISourceReader
{
public MetaCode ReadCode(string sourceCode)
{
// etc..
}
// etc..
}
public abstract class VisualBasicLikeSourceReader : ISourceReader
{
public MetaCode ReadCode(string sourceCode)
{
// etc..
}
// etc..
}
public abstract class AssemblyLanguageLikeSourceReader : ISourceReader
{
public MetaCode ReadCode(string sourceCode)
{
// etc..
}
// etc..
}
This way, when adding a new language you have the option to inherit from one of these pre-existing base classes, with the option to fall back on the interfaces if none of the them are suitable.
Related
I've used this pattern many times in a variety of places, usually alongside a plugin pattern.
Some example ways I've used it are for messaging systems, such as creating subscribers to various types of unrelated messages. I've also used it for generic integration workflows that each need a differently shaped context object.
Basically the pattern consists of defining a blank marker interface for a message or context. Then defining a high level workflow interface that works with the message/context interface. You can then use a factory to get a concrete instance of the workflow, and if needed, the workflow can also be responsible for parsing its message / context from a common data format.
Next, you create an abstract generic base workflow whose responsibilty is just to map calls to the interface methods, which pass around the useless marker interface, into calls to abstract methods that take the concrete version of the message/context.
Hopefully that makes sense. I'll provide a code example below. I'd love to know if this pattern has a name because I've noticed that I've used it about 4-5 times now. Also, I'm just fleshing out how to explain the pattern, so if anything about my explanation doesn't make sense please let me know that as well.
The main point is that you can have multiple classes with different method signatures that can still be called via a common interface:
End Result
public class ConcreteA : Base<MessageA>
{
public void Process(MessageA message){...}
public MessageA Parse(IDictionary data){...}
}
public class ConcreteB : Base<MessageB>
{
public void Process(MessageB message){...}
public MessageB Parse(IDictionary data){...}
}
//And both can by called by...
public void Main(){
var data = GetDataFromIntegrationSource(someContext);
IWorkflow impl = Factory.GetConcrete(someContext);
//So in your classes you're able to work with strongly typed parameters,
//But in the consuming code you still can use a common interface
//Consuming code never even knows what the strong type is.
IMessage msg = impl.Parse(data);
impl.Process(msg);
}
FULL EXAMPLE
High Level Interfaces
public interface IGenericeMarkerInterface
{
}
public interface IGenericWorkflow
{
void Process(IGenericeMarkerInterface messageOrContext);
IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat);
}
Abstract Base for Mapping to Concrete Methods
public abstract class GenericWorkflowBase<T> : IGenericWorkflow where T : IGenericeMarkerInterface
{
public void Process(IGenericeMarkerInterface messageOrContext)
{
Process((T)messageOrContext);
}
public IGenericeMarkerInterface Parse(IDictionary<string, string> commonDataFormat)
{
return DoParse(commonDataFormat);
}
public abstract void Process(T messageOrContext);
public abstract T DoParse(IDictionary<string, string> commonDataFormat);
}
Mapping Attributes
public class MappingAttributeUsedByFactoryAttribute : Attribute
{
public WorkflowType SomePropertyForMapping { get; set; }
}
Concrete Implementations
public class SomeRandomlyShapedMessageOrContext : IGenericeMarkerInterface
{
public int ID { get; set; }
public string Data { get; set; }
}
[MappingAttributeUsedByFactory(WorkflowType.IntegrationPartnerB)]
public class ConcreteWorkflow : GenericWorkflowBase<SomeRandomlyShapedMessageOrContext>
{
public override void Process(SomeRandomlyShapedMessageOrContext messageOrContext)
{
//TODO: process the strongly typed message
}
public override SomeRandomlyShapedMessageOrContext DoParse(IDictionary<string, string> commonDataFormat)
{
//TODO: parse the common data into the strongly typed message
}
}
Factory
public static class WorkflowFactory
{
public static IGenericWorkflow Get(WorkflowType workflow)
{
//TODO: find the concrete workflow by inspecting attributes
}
}
Example Usage
public static class Program
{
public static void Main(string[] args)
{
//this could be driven by a UI or some contextual data
var someSortOfWorkflowIdentifier = (WorkflowType)args[0];
var data = GetSomeDictionaryOfData();
var workflow = WorkflowFactory.Get(someSortOfWorkflowIdentifier);
workflow.Process(workflow.Parse(data));
}
}
Yes, it's exactly same as you named it: Marker interface
I am looking for a design pattern for a base class that forces all derived classes to implement all base class methods, while the methods in the derived classes have different return types. The scenario is a generic MemoryObject class (interface/abstract), keeping and returning whatever kind of objects in/from memory. But the derived classes (static/sealed/singleton) should return the correct type.
So the requirements are
- force all derived classes to implement all properties and methods of the base class
- methods in derived classes must return correct type
Here's some sample code, not compilable, but for illustration:
public interface MemoryObject
{
object FromMemory { get; }
//... other properties and methods
}
public sealed class MemoryObjectA : MemoryObject
{
public static List<string> FromMemory
{
get { return new List<string>(); }
}
//... other properties and methods
}
public sealed class MemoryObjectB : MemoryObject
{
public static DataTable FromMemory
{
get { return new DataTable(); }
}
//... other properties and methods
}
Thanks for your suggestions in advance!
It sounds like you just need to make it generic:
public interface MemoryObject<T>
{
T FromMemory { get; }
//... other properties and methods
}
public class MemoryObjectA : MemoryObject<List<string>> { ... }
public class MemoryObjectB : MemoryObject<DataTable> { ... }
Note that the implementation methods will have to be instance methods, not static methods. (You can make the implementations singletons though, should you wish.)
I am trying to find the right way to use a Generic List of Generic Interfaces as a variable.
Here is an example. It is probably not the best, but hopefully you will get the point:
public interface IPrimitive<T>
{
T Value { get; }
}
and then in another class, I want to be able to declare a variable that holds a list of objects that implement IPrimitive<T> for arbitrary T.
// I know this line will not compile because I do not define T
List<IPrimitive<T>> primitives = new List<IPrimitives<T>>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive<X>
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive<Y>
Note that the T in IPrimitive<T> could be different for each entry in the list.
Any ideas on how I could setup such a relationship? Alternative Approaches?
public interface IPrimitive
{
}
public interface IPrimitive<T> : IPrimitive
{
T Value { get; }
}
public class Star : IPrimitive<T> //must declare T here
{
}
Then you should be able to have
List<IPrimitive> primitives = new List<IPrimitive>;
primitives.Add(new Star()); // Assuming Star implements IPrimitive
primitives.Add(new Sun()); // Assuming Sun implements IPrimitive
John is correct.
Might I also suggest (if you are using C# 4) that you make your interface covariant?
public interface IPrimitive<out T>
{
T Value { get; }
}
This could save you some trouble later when you need to get things out of the list.
You say it won't work because you don't define T. So define it:
public class Holder<T>
{
public List<IPrimitive<T>> Primitives {get;set;}
}
This is one of the most complicated elements of the c# language though it is incredibly important for building well defined components. As such, c# falls short. However it is definitely possible to make this work.
The trick is to have 3 parts:
A non generic interface that contains all requirements of the interface.
A generic abstract class that implements the non generic interface and performs the type conversions as necessary.
A class that implements the generic abstract class with the appropriately typed results
For example:
public interface INonGenericInterface{
void Execute(object input);
object GetModel();
}
public abstract class IGenericInterfaceBase<T> : INonGenericInterface{
void INonGenericInterface.Execute(object input){
Execute((T) input);
}
object INonGenericInterface.GetModel(){
return GetModel();
}
protected abstract void Execute(T input);
protected abstract T GetModel();
}
public class ImplementingClass : IGenericInterfaceBase<ModelClass>{
protected override void Execute(ModelClass input){ /*Do something with the input */ }
protected override ModelClass GetModel(){ return new ModelClass();}
}
//Extras for demo
public class ModelClass { }
public class ModelClass2 { }
public class ImplementingClass2 : IGenericInterfaceBase<ModelClass2>
{
protected override void Execute(ModelClass2 input) { /*Do something with the input */ }
protected override ModelClass2 GetModel() { return new ModelClass2(); }
}
var agi = new INonGenericInterface[] { new ImplementingClass(), new ImplementingClass2() };
agi[0].Execute(); var model = agi[0].GetModel();
agi[1].Execute(); var model2 = agi[1].GetModel();
//Check the types of the model and model2 objects to see that they are appropriately typed.
This structure is incredibly useful when coordinating classes w/ one another because you're able to indicate that an implementing class will make use of multiple classes and have type checking validate that each class follows established type expectations. In addition, you might consider using an actual class instead of object for the non-generic class so that you can execute functions on the result of the various non-generic calls. Using this same design you can have those classes be generic classes w/ their own implementations and thus create incredibly complex applications.
To OP: Please consider changing the accepted answer to this to raise awareness of the correct approach as all previously stated answers fall short for various reasons and have probably left readers with more questions. This should handle all future questions related to generic classes in a collection.
Here is an example. I have two classes, one inherited, and both have a function with the same name, but different arguments:
public class MyClass
{
//public class members
public MyClass()
{
//constructor code
}
public void Copy(MyClass classToCopy)
{
//copy code
}
}
public class InheritedClass : MyClass
{
//public class members
public InheritedClass():base()
{
//constructor code
}
public void Copy(InheritedClass inheritedClassToCopy)
{
//copy code
}
}
My question is how do I make the base class' copy method (MyClass.Copy) non-inheritable or non-visible in InheritedClass? I don't want to be able to do this:
MyClass a;
InheritedClass b;
b.Copy(a);
Does this make sense, or should I keep this functionality in there? Can what I'm asking even be done?
Does this make sense, or should I keep this functionality in there? Can what I'm asking even be done?
Trying to hide a public method like this when used by a base class is problematic. You're purposely trying to violate the Liskov substitution principle.
You can't do what you are wanting to do here; C# does not allow negative variance in inherited members. (almost no languages truly do, actually)
It may be that you don't want an inherited class here at all, though; what you may really want is an interface. Or... your two classes here may not have the correct relationship; perhaps they should both instead be common siblings of a third class, which is their parent.
You can use explicit interface implementation to hide this method from the inheritor. But you will need to add an interface of course and you will need to cast your type to the interface to call your method:
public interface MyInterface
{
void Copy(MyClass classToCopy)
}
public class MyClass : MyInterface
{
void MyInterface.Copy(MyClass classToCopy)
{
//copy code
}
}
This is not possible. An inherited class inherits all public and protected members, methods and properties. Using the sealed modifier with make it non-overridable, but still accessible to your inherited class.
What everyone else said, but if I am inferring your goal correctly, it is to make sure that InheritedClass users never use the MyClass method. In that case, exclude it from MyClass and make two classes that inherit it.
Make MyBaseClass abstract if it should not be instantiated (most likely).
(Edited -- you probably would want to include copy code for anything that's part of the base class in the base class)
public abstract class MyBaseClass
{
public MyClass()
{
//constructor code
}
protected void Copy(MyBaseClass classToCopy)
{
//copy code
}
// other methods that all inherited classes can use
}
public class MyClass: MyBaseClass
{
public MyClass():base()
{
//constructor code
}
public void Copy(MyClass myClassToCopy)
{
base.Copy(myClassToCopy);
//specific copy code for this extensions in this class
}
}
public class InheritedClass : MyBaseClass
{
public InheritedClass():base()
{
//constructor code
}
public void Copy(InheritedClass inheritedClassToCopy)
{
base.Copy(myClassToCopy);
//specific copy code for this extensions in this class
}
}
In C#, I have a class hierarchy with a couple of abstract base classes near the top and a fair number of derived classes. A few these concrete classes have some common properties and methods that are implemented identically. It strikes me as wasteful and so one solution might be to implement this common behaviour in another abstract base class.
abstract class Control;
abstract class SquareControl: Control
{
public int SquarishProperty;
public void SquarishMethod();
};
class Window: SquareControl;
class Button: SquareControl;
However, what if several other classes in the hierarchy shared some other behaviour but also share something in common with one of the controls from another base class? Perhaps there are lots of areas of commonality. It would become impractical to model this with abstract base class implementation wouldn't it?
abstract class FlashableControl: Control
{
public int FlashyProperty;
public void FlashMethod();
};
class StatusBar: FlashableControl; // but it's also a bit square too, hmm...
So how do you go about sharing such implementations across classes without using base classes?
I imagine I want to delegate the implementaion of an interface to another class and have that class implement those properties and methods on behalf of the desired classes, so that to the user, the StatusBar and Window appear to support a standard interface, but under the covers it's something else that implements it.
I can visualise aggregating classes that implement this behaviour, but is this appropriate and are there any pitfalls? What are the alternatives?
Thanks
You can use a pattern like this:
public interface ICommonServices
{
string SomeProperty { get; set; }
void SomeMethod(string param);
}
public static class CommonServiceMethods
{
public static void DoSomething(this ICommonServices services, string param)
{
services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
}
}
All classes that implement ICommonServices now also get some free behavior via the extension method, which depends solely on those features exposed by all ICommonServices implementers. If you need access to base class functionality, you can put that in its own interface and have ICommonServices implement that interface as well. Now you can create 'default' extension functionality for interfaces without having to use multiple base classes.
EDIT
If you want some of these methods to be internal, you can modify the pattern like this:
public class MyObject : IServices
{
public string PublicProperty { get; private set; }
string IServices.SomeProperty { get; set; }
void IServices.SomeMethod(string param)
{
//Do something...
}
}
public interface IPublicServices
{
string PublicProperty { get; }
}
internal interface IServices : IPublicServices
{
string SomeProperty { get; set; }
void SomeMethod(string param);
}
internal static class ServiceMethods
{
public static void DoSomething(this IServices services, string param)
{
services.SomeMethod(services.SomeProperty + ": " + param + " something extra!");
}
}
Basically we're exposing both public and internal interfaces. Note that we implement the internal interface methods explicitly, so that the methods are not available for public consumption (since the public client can't get access to the interface type.) In this case, the helper extension methods are internal, relying on the internal interface, though you could also create public helper methods that rely on the public interface.
You could use 'has-a' instead of 'is-a' and delegate to an internal square control
class Window : Control, ISquareControl
{
private SquareControl square;
public void SquareOperation()
{
square.SquareOperation();
}
}
class SquareControl : Control, ISquareControl
{
public void SquareOperation()
{
// ...
}
}
One way is to use Interfaces and Base Classes.
Flashable would make a good Interface instead of a class.