简体   繁体   中英

How to I implement this Base/Derived class structure?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM