How to cleanly manage classes and components with multiple interfaces? - c#

I have a Car which is an ICar, an IFuelPowered and an IVehicle
My Car contains a CarData class, which is an ICarData, an IFuelPoweredData, and an IVehicleData
Whilst the Car class holds behaviour logic, the data interfaces present various properties, for example:
ICarData:
Brand
IFuelPoweredData:
TankSize
IVehicleData
MaxSpeed
Within the Car class, I'd like to include only ICarData as a property (which inherits from the IFuelPoweredData and IVehicleData interfaces, and therefore complies with all these contracts)
But instead I have to do this:
IVehicleData IVehicle.Data => Data;
IFuelPoweredData IFuelPowered.Data => Data;
public ICarData Data { get; }
Else the compiler complains the interfaces on IFuelPowered and IVehicle are not implemented. This is because for example, IFuelPowered has IFuelPoweredData on its interface.
This confuses me because Car does have a property of ICarData (which itself implements IFuelPoweredData and IVehicleData).
Is there a cleaner approach to this style of problem?

You can just implement IFuelPoweredData and IVehicleData in ICarData.
public interface ICarData : IFuelPoweredData, IVehicleData
{
//Contents of interface
}
The you will only need an ICarData property in your Car class.

Related

Making arrays to hold polymorphed generics

The question I asked here brought me thus far on my project:
abstract class Base<T> where T:ContentBase
{
//base functionality
}
class Foo : Base<FooContent>
{
//overrides
}
class Bar : Base<BarContent>
{
//overrides
}
Is there a way to make an array or List that can hold both Foo and Bar objects or would I have to look at making a record or something?
Thanks in advance.
You could add a non-generic abstract class Base that Base<T> inherits from, and then make a List<Base>. So extending your code might look something like this:
abstract class Base
{
//base functionality (non-generic)
}
abstract class Base<T> : Base where T : ContentBase
{
//base functionality acting on T
}
class Foo : Base<FooContent>
{
//overrides
}
class Bar : Base<BarContent>
{
//overrides
}
I'm assuming from the example code that FooContent and BarContent derive from ContentBase. I'm also assuming that the code follows the SOLID principles and especially LSP.
A generic collection could be defined in terms of ContentBase.
var collection = new List<ContentBase>();
The collection can hold instances of FooContent, BarContent, and ContentBase.
But apparently that is a need to hold the ContentBase and derived types within another type. (It is not clear from the question why this is needed.)
public class ContentAdaptor
{
public ContentAdaptor(ContentBase content)
{
_content = content;
}
...
private ContentBase _content;
}
The ContentAdaptor type holds a reference to an instance of ContentBase. The instance could be of a derived type.
A collection of ContentAdaptor:
var collection = new List<ContentAdaptor>();
I have a suspicion that FooContent and BarContent may violate LSP and are not substitutable for each other. Is that the case? If you have types that are fundamentally different but you want to process the objects in a polymorphic way, consider an interface.
public interface IProcess
{
bool Process();
}
Here ContentBase implements the IProcess interface. But note that a SomeOtherContent type that doesn't derive from ContentBase can also implement the IProcess interface.
public class ContentBase : IProcess
{
// Implement the IProcess interface.
}
A collection of IProcess:
var collection = new List<IProcess>();
The Process method can be called on each object in the collection. Each type provides its own implementation of the Process method.

Can I define a method of interface type inside a class

abstract class someClass
{
public abstract IProduct SomeMethod();
}
public interface IProduct
{
string Operation();
}
I have seen the above code having a method define inside abstract class with type interface, I wonder the use of this. Can anybody explain?
You are asking about this:
abstract class SomeBaseClass
{
public abstract IProduct SomeMethod();
}
In this case, IProduct may represent any object that implements the interface, and the method SomeMethod() is guaranteed to return an object of some class implementing IProduct.
This has many uses where the design dictates that all classes that derive from SomeBaseClass be able to create objects that adhere to the IProduct interface.
In c# interfaces are like contracts that guarantee specific behavior and properties.
This means that regardless of the actual implementation, code like this below is valid
SomeBaseClass f = ...
IProduct p = f.SomeMethod();
string op = p.Operation();

Need to derive the decorator from component in decorator design pattern

I was going through design patterns tutorials and came across decorator patterns. I got a idea of how and when the decorator pattern is used however, I am bit confused on why the decorator needs to be derived from the component.
The example I saw was something as below :
//Component classes
public abstract class Car
{
public abstract int GetPrice();
//Other properties and methods
}
public class ActualCar : Car
{
public int GetPrice(){return 1000;}
}
//Decorators classes
public class CarDecorator : Car //No idea why this is necessary
{
protected Car car;
public CarDecorator(Car car)
{
this.car = car;
}
public override int GetPrice() => this.car.GetPrice();
}
public class LeatherSeats : CarDecorator
{
public LeatherSeats(Car car) : base(car){}
public override int GetPrice() => this.car.GetPrice() + 200;
}
public class AlloyWheels : CarDecorator
{
public AlloyWheels(Car car) : base(car) {}
public override int GetPrice() => this.car.GetPrice() + 150;
}
Now when using the component along with its decorators we use it as :
Car newCar = new ActualCar();
int price = new AlloyWheels(new LeatherSeats(newCar)).GetPrice();
Now I thought it was weird that the CarDecorator was inherited from Car as no matter how you look at it doesn't follow the is-a type of relationship. So I looked at few more examples and realized that it is how the decorator pattern is designed as.
I don't want to question the reason why the decorator pattern was designed this way, but just want to know what will be the cons of not having decorator pattern be derived from component it wraps.
Your CarDecorator which is a base decorator should inherit Car interface (here it's an abstract class) to ensure that CarDecorator has implemented (should override) GetPrice method.
If CarDecorator does not inherit from Car, then you can't do like this:
Car newCar = new ActualCar();
int price = new CarDecorator(newCar).GetPrice();
Car serves here pretty much like an interface, or a contract that explicitly tells that all concrete decorators should implement GetPrice method.
The purpose of the Decorator pattern is to provide a way to extend a class without subclassing.
"Attach additional responsibilities to an object dynamically keeping
the same interface. Decorators provide a flexible alternative to
subclassing for extending functionality." (Gang of Four)
This means for the client the decorator type must behave exactly like (mimic) the decorated type. Even more, the decorator type must be replaceable to the decorated type.
To make types replaceable they must be of the same base type:
interface IVehicle {}
class Car : IVehicle {}
class Bus : IVehicle {}
Now every IVehicle is replacable:
IVehicle car = new Car();
IVehicle bus = new Bus();
IVehicle vehicle = car;
vehicle = bus;
To allow the decorator type to be replaceable with the decorated type both must inherit the same base type. This means the decorator will actually extend the decorated base type:
// Common base class. Will be extended by a decorator.
public interface ICar
{
ISound Honk();
//Other properties and methods
}
public class Beagle : ICar
{
// Implementation of ICar
public ISound Honk() => new BeagleHornSound(); // BeagleHornSound implements ISound
}
// Abstract decorator base class.
// Since the base class implements ICar, every CarDecorator "is-a" ICar.
// This makes CarDecorator and every ICar replaceable and allows the CarDecorator to mimic the decorated/wrapped ICar.
// Therefore every feature of this class or subclass is actually extending every ICar.
public abstract class CarDecorator : ICar
{
private ICar Car { get; set; }
private CarDecorator(ICar car)
{
this.Car = car;
}
// Implementation of ICar
public ISound Honk() => this.Car.Honk();
}
// Concrete decorator class
public abstract class Lowrider : CarDecorator
{
private Hydraulics Hydraulics { get; set; }
public CarDecorator(ICar car) : base (car)
{
this.Hydraulics = new Hydraulics();
}
public void EnableHydraulic() => LetCarHop();
}
Usage
// Extends the ICar by wrapping it into a decorator
public CarDecorator PimpCar(ICar car)
{
return new Lowrider(car);
}
ICar beagle = new Beagle(); // Beagle implements ICar
CarDecorator lowrider = PimpCar(beagle); // Returns a Lowrider which extends CarDecorator
// Since the decorator also implements ICar, every CarDecorator is replaceable with every other ICar
ICar pimpedBeagle = lowrider; // Lowrider implements ICar
// Since the decorator "is-a" ICar, it can mimic every ICar
ISound hornSound = lowrider.Honk();
// Since the Lowrider is decorating/wrapping currently a Beagle, it actually mimics a Beagle
bool isSameType = lowrider.Honk() is BeagleHornSound; // true
Now you can see, that if the decorator won't implement the same type it is decorating, then you wouldn't have the decorated type extended, but created a new type.
You usually extend a type by inheriting from it and the add new features to the subclass. The Superclass (ancestor) is extended because the subclass (descendant) is still of the same type like its superclass (that's inheritance - same inheritance tree).
Decorator is just another strategy to achieve the same result, but without subclassing the type you wish to extend.
The decorator type (descendant) is actually the extended version of the decorated type (ancestor). It's like the decorator is a subclass (extension) of the decorated type.
To realize this in terms of type hierarchy, the decorator must be also of the same type like the superclass in order to be a true descendant. Basically the Decorator is faking inheritance using composition. Or the Decorator is a more flexible form of inheritance, as every type wrapped by a single decorator is actually extended without writing a new derived class of the wrapped type.

Is is legal to use a interface variable to potentially hold an object of different classes in a domain model?

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?
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).

How can I get the derived primitive type from a generic interface?

Been struggling with this for a bit so wanted to see if someone here might know the solution. I have a set of interfaces (and an implementation):
public interface IInputValue
{
}
public interface IInputValue<T> : IInputValue where T : struct
{
T Value { get; set; }
}
public class ButtonInputValue : IInputValue<bool>
{
private bool m_Value;
public bool Value
{
get => m_Value;
set => m_Value = value;
}
}
And then I have a scriptable object class that inherits and uses implementations of IInputValue<T>.
public abstract class InputTrigger : ScriptableObject
{
}
public abstract class InputTrigger<T> : InputTrigger where T : IInputValue
{
public abstract T InputValue { get; }
}
T for example, could be ButtonInputValue. I want to serialize this scriptable object in another class (as InputTrigger) and simply be able to call .InputValue on it to get the correct derived type of IInputValue or just get the primitive value directly through IInputValue<T>.Value. What's the best way to go about doing this? Any help is much appreciated.
I think you are trying to use interfaces in the wrong way.
The purpose of an interface is to abstract common functionality on potentially completely different objects and not caring about the base class that implements the interface.
For instance:
You can have a car object and a electric car objects and they can both accelerate and brake. They do so in different ways but all you need to know is that they can accelerate and brake using the pedals (the interface), without you going to learn to drive a car once again.
To answer your question, I think you can use the interface as a type and call the method on the object, and in case you need to verify it is a certain type that implements that interface you can cast to it.
IInputValue<bool> myInputValue;
(ButtonInputValue) myInputValue; // This will be treated as ButtonInputValue because the class implements the IInputValue interface.

Categories

Resources