0

In my project, I want to implement the SOLID principles, so that my code may be easier to test and extend later down the line. For this purpose, I am curious if I can use Liskov's Substitution Principle in order to make testing of code easier, by having a production class and a testing class both inherit an interface and act in it's place.

Interface + Object classes

public interface Iinterface {
     int commonVariable { get; set; }
}

public class ProductionClass : IInterface{
     public commonVariable { get; set; }

     //Production variables + functions

     public ProductionClass() {}
}
public class TestClass : IInterface {
     public commonVariable { get; set; }

     //Test variables + functions

     public TestClass() {}
}

Domain Model

public class DomainModel() {
     //Could object be either of ProductionClass or TestClass without breaking my database?
     public virtual IInterface object { get; set; } 
}

As ProductionClass and TestClass both inherit IInterface, I know that object of either class can be placed in a IInterface variable.

However, when constructing a database, would a IInterface object be valid?

Would it hold all the data of whatever class gets passed to it, or just the data specified when the interface was defined?

What would happen If I tried to insert an object of a different class in the object? Would the columns for the table be overwritten with the new class' variables?

Should I even be attempting to make TestClass, at this rate?

Muroxxas
  • 158
  • 1
  • 1
  • 10

1 Answers1

1

The class design you show is not an example of LSP (Liskov Substitution Principle). It's rather an example of DI (Dependency Inversion): the concretions (DomainModel) depend on abstractions (IInterface).

To have an LSP case, you'd need:

class Base { }

class Derived : Base { }

void Process(Base item)
{
    // here, the method shall not care whether 'item' is in fact
    // an instance of 'Base' or 'Derived'
}

"Inherit an interface" is incorrect. "Implement an interface" is correct. The classes cannot inherit interfaces, only implement them.

Having a variable (or a field, or a property) of type IInterface, you can only tell the following: the object I have implements that interface. You have no knowledge about the concrete type of the object - whether it is a TestClass, a ProductionClass or a ThirdPartyClass (unless you check for type explicitly of course). The object might be completely different internally. It might contain all the data you need or no data at all.

As a design suggestion: use interfaces to abstract your services and business entities. Use concrete types (POCO) to represent your DTOs (Data Transfer Objects).

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • Thanks for the information. Just to clarify, when you say to use POCO for DTOs, you mean that domain model objects should not implement any interface, nor use any interface objects within themselves, correct? – Muroxxas Jun 08 '20 at 17:30
  • Domain model is not necessary the same as DTO (entity model). Read [this great answer](https://stackoverflow.com/a/18113611/2846483) for details. Also, check out [this question](https://stackoverflow.com/q/24588838/2846483) and answers. – dymanoid Jun 08 '20 at 19:11