I have completed an ETL project to collect, parse and load files. I decided to make it clean OOP way using interfaces and abstract, but have some questions below.
Sub Main() Dim collectionOfParsers As New List(Of EtlParser) Dim xmlparser1 As New XmlParser Dim xmlparser2 As New XmlParser Dim xmlparser3 As New XmlParser Dim txtparser1 As New TxtParser Dim txtparser2 As New TxtParser collectionOfParsers.Add(xmlparser1) collectionOfParsers.Add(xmlparser2) collectionOfParsers.Add(xmlparser3) collectionOfParsers.Add(txtparser1) collectionOfParsers.Add(txtparser2) For Each parser As EtlParser In collectionOfParsers parser.SaySomething() Dim canOpenFiles = TryCast(parser, ICanOpenFiles) If (canOpenFiles IsNot Nothing) Then canOpenFiles.OpenFiles() End If Dim canReadFiles = TryCast(parser, ICanReadFiles) If (canReadFiles IsNot Nothing) Then canReadFiles.Readfiles() End If Dim canTransFiles = TryCast(parser, ICanTransformFiles) If (canTransFiles IsNot Nothing) Then canTransFiles.TransformFile() End If Dim canSaveFiles = TryCast(parser, ICanSaveFiles) If (canSaveFiles IsNot Nothing) Then canSaveFiles.Savefiles() End If Next End Sub Public MustInherit Class Etl End Class Public MustInherit Class EtlParser : Inherits Etl Protected Sub CanParse() Console.WriteLine("Yes") End Sub Protected Overridable Sub SaySomething() Console.WriteLine("EtlParser say something") End Sub Protected MustOverride Sub CanParseFormat() End Class Public Interface ICanOpenFiles Sub OpenFiles() End Interface Public Interface ICanReadFiles Sub Readfiles() End Interface Public Interface ICanSaveFiles Sub Savefiles() End Interface Public Interface ICanTransformFiles Sub TransformFile() End Interface Public Class XmlParser : Inherits EtlParser Implements ICanOpenFiles, ICanReadFiles, ICanTransformFiles, ICanSaveFiles Public Sub OpenFiles() Implements ICanOpenFiles.OpenFiles Throw New NotImplementedException() End Sub Public Sub Readfiles() Implements ICanReadFiles.Readfiles Throw New NotImplementedException() End Sub Public Sub TransformFile() Implements ICanTransformFiles.TransformFile Throw New NotImplementedException() End Sub Public Sub Savefiles() Implements ICanSaveFiles.Savefiles Throw New NotImplementedException() End Sub Protected Overrides Sub CanParseFormat() Throw New NotImplementedException() End Sub Protected Overrides Sub SaySomething() 'MyBase.SaySomething() Console.WriteLine("XmlParser say something") End Sub End Class Public Class CsvParser : Inherits EtlParser Implements ICanOpenFiles, ICanReadFiles, ICanTransformFiles, ICanSaveFiles Public Sub OpenFiles() Implements ICanOpenFiles.OpenFiles Throw New NotImplementedException() End Sub Public Sub Readfiles() Implements ICanReadFiles.Readfiles Throw New NotImplementedException() End Sub Public Sub TransformFile() Implements ICanTransformFiles.TransformFile Throw New NotImplementedException() End Sub Public Sub Savefiles() Implements ICanSaveFiles.Savefiles Throw New NotImplementedException() End Sub Protected Overrides Sub CanParseFormat() Throw New NotImplementedException() End Sub Protected Overrides Sub SaySomething() 'MyBase.SaySomething() Console.WriteLine("CsvParser say something") End Sub End Class
Q1: Once i collect the files from network drive (this will be done by Collector later on). What is your opinion should i make xmlparser class to handle many files or just one? If the second option then as you can see i created already many xmlparser instances (1 instance per each file), however i am not sure here maybe should i have xmlparser prepared for all files and then call it just once?
Q2: Regarding the for each loop i parametrized common type as EtlParser to pass diffrent specific parsers (is it ok by the way?). Can you explain me how it's possible specific parser within the loop is seen as passed object type - for instance i passed XmlParser and within i see it as well - i thought that when passing specific parser e.g XmlParser through parameter (his parent - EtlParser) it becomes EtlParser and i have to cast it again to XmlParser again inside loop. Would like to understand that.
Q3: As long as i know definition of interfaces e.g "Need to provide common functionality to unrelated classes" what in my example code is real benefit as all of my specific parsers uses the same interfaces at the end? All can open, read, transform and save...
Q4: As you see i have 3 specific parser classes: CsvParser, XmlParser, TxtParser inheriting from their base EtlParser class. Wouldn't it be better to make one parser class and instead make interface IXml, ITxt, ICsv which will be implemented? At this moment i think what i have is proper.
Q5: Why in the Main method i cannot do: parser.SaySomething() However when i look at parser item it shows exactly correct type.
Q6: Any ideas, advices to my current code besides?