Quantcast
Channel: User user2023861 - Code Review Stack Exchange
Viewing all articles
Browse latest Browse all 35

Answer by user2023861 for Demonstration of inheritance with some shapes

$
0
0

Your code doesn't benefit from the use of inheritance. You can remove all references to IShape without losing anything. If you had an illustrator class that accepted IShape objects, then you'd have something but it feels forced.

I tend to avoid inheritance. They say we should prefer composition over inheritance. One thing I look for in my code is switch statements and enums. I have found that if I replace them with polymorphism, my code becomes cleaner.I can add the equivalent of switch-cases without changing existing code.

Example using switch statements:

enum FileType { xlsx, xml, csv }public void GenerateFile(DataType data, FileInfo dest, FileType type){    switch(type)    {        case FileType.xlsx:            GenerateXlsx(data, dest);            break;        case FileType.xml:            GenerateXml(data, dest);            break;        case FileType.csv:            GenerateCsv(data, dest);            break;        default:            throw new NotImplementedException();    }}

In this case, your code supports three FileTypes and your switch statement controls which method to call based on your FileType parameter. If you add a FileType "dat" to your enum, you have to add a case to each of your switch statements. This is error-prone if you have many switch cases as adding the "dat" value to the enum could be a breaking change. If you don't have access to source code that uses these enums your problem is exasperated.


Example using inheritance:

public abstract class FileGenerator{    void GenerateFile(DataType data, FileInfo dest)    {        byte[] fileContents = this.OnGenerateFile(data);        File.Write(dest.FullName, fileContents);    }    protected abstract byte[] OnGenerateFile(DataType data);}public class FileGeneratorXlsx : FileGenerator{    protected override byte[] OnGenerateFile(DataType data)    {        //code to generate bytes    }}

The benefits to inheritance here are that when you deal with a FileGenerator type, you don't have to use a switch statement containing a case for every type of FileGenerator. You might use a Factory like this:

public void GenerateDataFile(IFileGeneraterFactory fileGeneratorFactory, DataType data){    FileGenerator fileGenerator = fileGeneratorFactory.Create();    fileGenerator.GenerateFile(data);}

Notice that you have no conditionals here. You don't care how the FileGenerator type is implemented, only that it has a GenerateFile(DataType) method. Your factory may even return an object that didn't exist when the abstract class FileGenerator was first implemented. An object in a different assembly and namespace. All you care is that this object satisfies the contract stating that it has a GenerateFile(DataType) method.

Note that I wrote this example in a way that you couldn't easily switch from using an abstract class to an interface. I've been asked the difference in job interviews before.


Viewing all articles
Browse latest Browse all 35

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>