3 ms·
Perhaps this would work: Build a program that... * That has a hardcoded list of strings baked into it * Accepts as inputs a filename (but can be empty) and a
by quietbritishjim 4y ago
Perhaps this would work: Build a program that...
* That has a hardcoded list of strings baked into it
* Accepts as inputs a filename (but can be empty) and a substring to search for
* At runtime, either (a) (if filename empty) iterates over hardcoded list of strings, or (b) opens file and iterates over lines in it
* For each string / line, if contains search string then output to stdout (and maybe also increment a counter).
It's very artificial but does allow the basic idea of OO to be illustrated and it's far less code than a GUI example. You have a base class and two derived classes that really do have a different mechanism, and even have different state (file handle or integer index). The program logic is also quite decoupled (the class interface is not tied to the fact you're doing string search).
You could solve the problem without classes by reading the whole file into the same list structure as the hardcoded strings, but that aspect is actually quite nice because you can present that first and then ask what to do if you want to avoid that unnecessary memory usage. It's also nice that you're illustrating a really common OO pattern (iterator).
The only slight downside is that some languages make this easy to do without (explicit) classes e.g. Python generator functions. But you can add a footnote that they exist and this is just to illustrate classes - it still beats the abstract examples.
- Joker_vD 4y agoRefactoring something along the lines of static void Main(string[] args) { var filename = args[0]; var needle = args[1]; var linesToProcess = filename != '' ? File.ReadAllLines(filename) : HardcodedLines; ProcessLines(linesToProcess, needle); } static void ProcesLines(string[] linesToProcess, string needle) { // lines-processing code... } into something like static void Main(string[] args) { var filename = args[0]; var needle = args[1]; var linesProvider = filename != '' ? FileLinesProvider(filename) : MemoryLinesProvider(HardcodedLines); ProcessLines(lineProvider, needle); } static void ProcesLines(ILinesProvider linesProvider, string needle) { var linesToProcess = linesProvider.GetLines(); // lines-processing code... } would still need some justification, IMO: what's the benefit of giving ILinesProvider to the ProcessLines instead of just string[]?
- deleted 4y ago[deleted]
- quietbritishjim 4y agoI'm not clear on what you GetLines() method is returning (thanks to the var keyword - very useful but sometimes problematic, this is one of those times). If your GetLines() is returning a string[] then I agree there was no benefit. But that's not what I meant. As I said, I'm imagining the base class (ILinesProvider) to have an iterator-like interface. So, rather than string[] GetLines() method, it would have a string getNextLine() method that you call in a loop. That way, with the file, you don't load the whole thing in memory (as I also said). If your GetLines() method is returning an IEnumerable<string> (since this seems to be C#) then this is the problem I mentioned at the end of my comment - the base class I'm imagining is similar to an existing base class in the language, and it's confusing to write your own similar-but-slightly-different version in an example. But I think it's best to do it anyway and explain it away in a footnote. (But my ILinesProvider wouldn't return an IEnumerable, like in your snippet - instead, ILinesProvider actually is the iterator (but with a slightly different interface).)