0

I am building a CMS and need guidance on how to structure the application. I simply do not understand when I should use interfaces or an abstract class.

The system being built is using .Net Core and EF core I plan to allow MySQL and SQL Server as datasource. I also want a modular approach where I can add things on a paid for basis for example e-commerce and payment module.

The design of the current layers is listed below

Database - Contains 3rd party dependency to EF Core

It contains all the BusinessEntities with multiple classes but two Interfaces one is IGenericProperties (Which has properties shared between classes e.g. IsDeleted) and IPrimaryKey, most entities implement these interfaces.

Also contains DataAccessLayer and one interface IGenericMethods this has multiple methods such as Add, Deleted, Retrieve etc which the GenericObject class implements. All other DAL classes then inherit GenericObject

Lastly the EF DatabaseContext is also specified in this layer.

Framework

This has framework content such as extension methods, searching and non-db related stuff.

Security

This has the ASP.NET Identity stuff such as UsersStore, Roles etc.

Lastly I have MVC and Tests layers.

The controllers in the MVC layers can then perform CRUD operations like this

    CategoriesDAL categoryObject = new CategoriesDAL();
    IList<Category> getAll = categoryObject.RetrieveAll().ToList();

However, upon reading more about Dependency Injection and layering (reading Adaptive Code: Agile coding with design patterns and SOLID principles (Developer Best Practices, Gary McLean)), I am questioning whether the approach I am going down is usable or whether I'd have issues in the future. A few things I can spot is how could I possibly make this modular such as adding e-commerce modules as I'd need to reference EF.

I have looked at source code examples on github of other CMS/Frameworks Umbraco,MrCMS, Orachard,Piranah. These systems do have a lot of layering and interfaces, and I am simply struggling to understand it.

So to sum up my question.

When and why should I use interfaces / abstract class?

How can I make my current application more modular ? (such as having e-commerce modules)

Thanks

3
  • 3
    Interfaces exist because when they designed abstract classes they couldn't get multiple inheritance to work. When they finally figured it out it was to late to change how the language worked without adding a new keyword like interface. That's why Java has the interface keyword. C# has it because C# is Java. Commented Sep 9, 2017 at 22:48
  • @CandiedOrange "C# is Java..." as someone who has used modern incarnations of C# and Java extensively... C# is so much more than Java.
    – Ant P
    Commented Sep 11, 2017 at 21:02
  • If you're going for OO programming, instead of procedural programming with data objects, then classes/interfaces should not expose properties anyway. Tell, don't ask. I recommend reviewing videos by Sandi Metz on OO, keeping in mind that her examples are in an dynamic language (uses unit tests in lieu of typed interfaces). Commented Sep 12, 2017 at 17:41

3 Answers 3

1

I simply do not understand when I should use interfaces or an abstract class.

The best way to understand the difference is the following:

  • Interfaces have an act as relationship
  • Subclasses have an is a relationship

Practically speaking, you use interfaces when you have a part of your code you want to be free to completely swap out. Interfaces work well when your design is based on composition (completely tested units assembled and working together).

You would use base classes when you want to share common behavior with all of the subclasses. Because the relationship between the base class and the child class is more intertwined, it is more difficult to perform unit testing. To be honest, the number of times where you need to share basic behavior with all child classes is a relatively small subset.

Examples of where Interfaces Work Well

Database access is one place where you actually want the ability to swap implementations out--even if it is just for testing. A common pattern is to use a Data Access Object (DAO) to separate the database calls from the rest of the business logic. If you've ever been in a position where the IT department has a change of policy and the database vendor you've been using costs too much, this helps minimize the impact on the rest of your system. You have the freedom to handle different database backends, integrate search servers (like ElasticSearch or Solr), etc. without breaking how your application functions.

Network access is another place where you want to be able to swap implementations out. It's one thing if your application needs to make network calls to hosted web services, but you can test the interaction without actually making a network call. It also allows you to adapt to different versions of web services or network protocols more quickly.

Subclasses are useful, too

I find subclassing more useful in desktop applications, particularly when I need to extend the controls that are provided to do something specific. However, they are much more difficult to test--both because it is a UI piece, and because of the subclass.

That said, you can consolidate boiler plate code that you might otherwise need to copy between different components. It's not an all or nothing solution. For example, the authorization helpers can work well as base class functionality.

Think carefully about whether sharing common behavior is the right answer, or whether you can simply use a fully self-contained object to provide the functionality.

0

> I simply do not understand when I should use interfaces or an abstract class

Rules of thumb that are woefully inadequate but certainly good starting points:

1 - Start off just creating classes as needed.

2 - Eventually, you find 2+ classes that do the same thing but are slightly different because of some lower level detail that the user of the class probably shouldn't care about. You need to decide if interface or abstract class is better.

  • 2.a - If the implementations of the 2+ classes are identical for most of the class's methods then create an abstract base class.

  • 2.b - Otherwise create an interface class.

FWIW - This is the almost totally "technically" incorrect way to make use of interface classes but it is the way at least 90%+ of developers use interface classes.

The more correct way to use interface classes is to create interfaces based on functionality rather than classes. The problem with that approach is the class explosion and cognitive dissonance it causes.

Most people can more easily handle class related functionality grouped together in interfaces because they've already identified that the classes "should" inherit from the same base. However, with the "technically" correct approach and the much larger number of interfaces to choose from, it becomes harder to find the "correct" interface(s) to base the class upon. I've seen projects that take the "technically correct" approach tending to have the problem where there are frequently a lot of almost-duplicate interface classes which exacerbates the class explosion problem even more.

Thus IMO, in the real world; "correct" is in the eye of the beholder. I now lean towards the rules-of-thumb approach described above with application of the "technically" correct approach when it "works" better for the situation. I am pointing out the "technically-correct" approach because it would do you an injustice not to make you aware that in the theoretical world interfaces are based on functionality and the above rules-of-thumb would be considered wrong. And this could be what you are seeing in the examples you are looking at. Pick which world you want to live in and try to be consistent. A mish-mash of both approaches is certainly not going to work out too well.

I am questioning whether the approach I am going down is usable or whether I'd have issues in the future.

The approach you are going down, and I don't even know what it is, is most certainly going to have issues in the future.

Unless you've built similar systems there's little possibility of getting it "right". Even if you've built nearly identical systems you'll still run into new issues that your design doesn't handle for the current specific project.

If most of your modules can be developed separately and independently from each other then consider that to be a great success. In order to accomplish that, you'll need to make good use of interfaces/abstract classes. Which answers the "Why you should use interfaces/abstract classes" question.

0

If you can't see where interfaces would help you, then it is likely you don't need interfaces. Interfaces are not in themselves a sign of good design, rather they are solution for specific problems. If you don't have the problem, you don't need the solution for it!

I suspect you are suffering by "analysis paralysis" because your requirements are to vague. E.g. what does "more modular" mean? Define what you want to achieve in concrete terms and then design the code to make this possible.