c# – The principle of open / closed when determining the file type dynamically

Question:

There is an application code in which it is necessary to dynamically determine the file type (HTML or TXT) by content and, depending on the received file type, call the appropriate processing algorithm.

interface IFileType
{
    void Process();
}
class HtmlFile : IFileType
{
    public void Process()
    {
        Console.WriteLine("HTML");
    }
}
class TxtFile : IFileType
{
    public void Process()
    {
        Console.WriteLine("TXT");
    }
}
class FileTypeHandler
{
    public static IFileType Define(string fileContent)
    {
        var file = fileContent.IndexOf("<html");
        if (file != -1)
        {
            return new HtmlFile();
        }
        else
        {
            return new TxtFile();
        }
    }
}
class FileProcessor
{
    public void ProcessFile(string fileName)
    {
        StreamReader fileStream = new StreamReader(File.OpenRead(fileName));
        string fileContent = fileStream.ReadToEnd();
        fileStream.Close();
        var fileType = FileTypeHandler.Define(fileContent);
        fileType.Process();            
    }
}   

class Program
{              
    static void Main(string[] args)
    {
        FileProcessor fileProcessor = new FileProcessor();
        fileProcessor.ProcessFile(@"d:\index.html");
        Console.ReadKey();
    }
}

Conclusion:

HTML

Everything works as I need. I'm interested in how flexible my code is to the emergence of new file types in the future , for example JSON. After all, with the advent of a new class that implements the IFileType interface, the algorithm for determining the type by content in the FileTypeHandler class will also change FileTypeHandler

Have I designed everything correctly regarding the principle of openness / closeness?

Answer:

I see the following issues in your code.

The FileTypeHandler method contains the definition logic, for all formats. At this stage, this is not scary, because. there are not many of them, but if their number increases, the method will become confusing and difficult to extend.

I recommend that you create entities for each format, and implement the definition in them. This will avoid confusion and make it easier to add new ones.

I will give the code, as I would implement in this situation. It has some minor simplifications. Written in java, but I think you will understand.

enum FormatTypes {
    TXT("txt", new TxtDetector()),
    HTML("html", new HtmlDetector());

    public final String name;
    private final Detector detector;

    FormatTypes(String name, Detector detector) {
        this.name = name;
        this.detector = detector;
    }
}

interface Detector {
    boolean isCorrectType(String fileName, String content);
}

class TxtDetector implements Detector {
}

class HtmlDetector implements Detector {
}

class DetectorHandler {
    public static String getType(String fileName) {
        String content = //чтение содержимого

        for (FormatTypes types : FormatTypes.values())
            if (types.detector.isCorrectType(fileName, content))
                //просто возвращает название формата, 
                //можно при необходимости в FormatTypes положить какую то логику
                return types.name;

        throw new IllegalArgumentException("type is not supported");
    }
}
Scroll to Top