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?