i have an abstract model named BetaModel that inherit its parent AlphaModel. Then
I have a bunch of request models that inherit the BetaModel and therefore naturally inherit AlphaModel, However I have the other bunch of response models which have to inherit the fields of BetaModel and do not need the fields in AlphaModel.
[Note: AlphaModel and BetaModel only contain some plain fields]
What is the elegant way to have the response models inherit the BetModel but ignore the AlphaModel?
Is it OK to turn the AlphaModel becomes an Interface, so that it only implemented in all the request models but not the response models?
So, you are basically contradicting the description with the "desired" architecture.
Also, always bare in mind that you don't decide architecture based on results ("Is it OK to turn the AlphaModel becomes an Interface"): your decisions are based on needs and responsibilities.
Interfaces
Think of that as a contract the classes are agreeing with. They don't hold any implementations and solely describe one contract the class implements
Abstract Classes
They are... Classes. As such, they don't define a contract, they define behaviours. And mostly, when defining an abstract class, you are looking for a abstract behaviour that you want children classes to inherit and/or give meaning to.
Your problem
You are saying some classes must inherit from AlphaModel and some others must NOT inherit from AlphaModel.
Therefore, you are saying that:
A certain class BetaModel1 inherits from AlphaModel and introduces some new members functionality.
Another class BetaModel2 should not expose any member from AlphaModel (which screams it doesn't inherit from AlphaModel) but also introduces the same members/functionality of BetaModel1
In other words, you are saying with all capital letters that BetaModel1 and BetaModel2 DO NOT INHERIT FROM THE SAME CLASS AlphaModel.
Now, back to our initial discussion. C# does not allow multiple inheritance (which looks like what you want to do). But there are strategies either to minimise re-writing code and/or enforce some implementations.
So, the "enforcing of implementation" is basically saying "I want this class to NECESSARILY provide certain functionality". Well... You need an interface for that
C#
public interface IBetaModel
{
string PropertyBeta { get; set; }
string MethodBeta();
}
There is also the AlphaModel
C#
public class AlphaModel
{
public string PropertyAlpha { get; set; }
public string MethodAlpha()
{
return "This is Alpha";
}
}
Now, your desired BetaModel1 (as described above) is quite simply inheriting from AlphaModel and implementing IBetaModel
C#
public class BetaModel1 : AlphaModel, IBetaModel
{
public string PropertyBeta { get; set; }
public string MethodBeta()
{
return "This is Beta?";
}
}
BetaModel2 it's just implementing IBetaModel, in which case:
C#
public class BetaModel2 : IBetaModel
{
public string PropertyBeta { get; set; }
public string MethodBeta()
{
return "This is Beta?";
}
}
The usage of the classes would be like:
C#
public void DoStuffWith(IBetaModel betaModel)
{
betaModel.PropertyBeta = "WOW, it works";
}
public void DoStuff()
{
var betaModel1 = new BetaModel1();
var betaModel2 = new BetaModel2();
AlphaModel betaModel1_ = new BetaModel1();
//AlphaModel betaModel2_ = new BetaModel2(); //won't compile
betaModel1.PropertyAlpha = "Test";
//betaModel2.PropertyAlpha = "Test"; //won't compile
DoStuffWith(betaModel1); //great!!!
DoStuffWith(betaModel2); //great too!!!
}
If this is only about data make every datapart an interface like...
public interface IAlphaModel
{
string SomeField { get; set; }
}
public interface IBetaModel
{
int AnotherField { get; set; }
}
public interface ISomeRequest : IAlphaModel, IBetaModel
{
bool YetAnotherField { get; set; }
}
class SomeRequest : ISomeRequest
{
public string SomeField { get; set; }
public int AnotherField { get; set; }
public bool YetAnotherField { get; set; }
}
public interface IAnotherRequest : IBetaModel
{
long TheUltimateField { get; set; }
}
class AnotherRequest : IAnotherRequest
{
public int AnotherField { get; set; }
public long TheUltimateField { get; set; }
}
Edit
Of course you can have the interfaces have more than one member if they are tied logically together.
Related
I am thinking about the best practice in OOP for the following problem:
We have a program that is working with an external API.
The API has an object of type Element which is basically a geometric element.
Our application is a validation application that runs on a geometric model
The application takes a collection of those elements and performs some geometric tests on them.
We wrap this API element with our own class called "ValidationElement" and save some additional information to this wrapper element that can not be obtained directly from the API Element but is required by our application.
So far so good, but now the application should expand and support other types of models (basically we can say that the app is running in a different environment).
Specifically for this environment (and it does not apply to the previous cases), we want to save an additional parameter that obtaining it results in low performance.
What is the best practice option to implement it?
On one hand, I would like to avoid adding extra parameters that are not relevant to a specific(the first) part of the program.
And on the second hand, I am not sure that I want to use inheritance and split this object just for this small additional property.
public class ValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
}
The first and easy option is that the same class will have the additional property and calculation method:
public class ValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
The second option that I mentioned is the inheritance
public class SecondTypeValidationElement : ValidationElement
{
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
What do you think is the best practice for this? Is there any other way or design pattern that should help me achieve the goal?
I would like to avoid adding extra parameters that are not relevant to a specific(the first) part of the program.
It looks like it is a sign that an inheritance shoulbe be avoided here. As there is a strong possibility that this behaviour is not applicable for other classes.
And this is the second reason to avoid of creation some abstraction:
Element which is basically a geometric element
Because:
all derived elements will have these additional properties.
there are many articles which show how Liskov substitution principle can be violated in geometry figures
So let's prefer composition over inheritance.
So, in my view, it would be really good if we move all heavy, tightly coupled logic of calculating of additional property to separate class:
public class ValidationElement
{
public string Element { get; set; }
public SomeExtra AdditionalProperty { get; set; }
}
public class SomeExtra
{
public string Location { get; set; }//The extra property
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = string.Empty;
}
}
Why have we created separate class SomeExtra and put logic here:
if we want to edit logic HardProcessingCalcOfAdditionalProperty, then we will edit just one class SomeExtra. By doing this we are satisfying Single Responsibility Principle of SOLID principles.
we can easily create some base abstract class for SomeExtra and then at runtime we can decide what concrete implementation should be injected. By doing this we are satisfying Open Closed Principle of SOLID principles.
UPDATE:
I really like this answer about whether inheritance or composition should be chosen:
My acid test for the above is:
Does TypeB want to expose the complete interface (all public methods no less) of TypeA such that TypeB can be used where TypeA is
expected? Indicates Inheritance.
e.g. A Cessna biplane will expose the complete interface of an airplane, if not more. So that makes it fit to derive from Airplane.
Does TypeB want only some/part of the behavior exposed by TypeA? Indicates need for Composition.
e.g. A Bird may need only the fly behavior of an Airplane. In this case, it makes sense to extract it out as an interface / class /
both and make it a member of both classes.
Update: Just came back to my answer and it seems now that it is incomplete without a specific mention of Barbara Liskov's Liskov
Substitution Principle as a test for 'Should I be inheriting from
this type?'
OOP and SOLID best practice is to use abstractions (interfaces or abstract classes), wich is closer to your second approach.
Dependency Inversion Principle:
The Dependency Inversion principle
states that our classes should depend upon interfaces or abstract
classes instead of concrete classes and functions.
Your first approach to edit the ValidationElement class is generally a bad idea, given that there are several environments for the project to be run onto.
In addition, maintaining and developing the project on this approach is not scalable and will be a headache in the long run.
Open-Closed Principle: The Open-Closed Principle requires that classes should be open for extension and closed to modification.
I suggest below designing:
public interface IValidationElement
{
Element Element { get; set; }
XYZ Location {get; set;}//The extra property
// declare other base properties and methods
}
public class ValidationElement: IValidationElement
{
public Element Element { get; set; }
public XYZ Location {get; set;}//The extra property
// define other base properties and methods
}
public interface ISecondTypeValidationElement: IValidationElement
{
string AdditionalProperty { get; set; }
void HardProcessingCalcOfAdditionalProperty();
}
public class SecondTypeValidationElement: ISecondTypeValidationElement
{
public string AdditionalProperty { get; set; }
public void HardProcessingCalcOfAdditionalProperty()
{
//hard processing
AdditionalProperty = result
}
}
public interface IThirdEnvironmentValidationElement: IValidationElement
{
string ThirdProperty { get; set; }
void RequiredProcessing();
}
public class ThirdEnvironmentValidationElement: IThirdEnvironmentValidationElement
{
public string ThirdProperty { get; set; }
public void RequiredProcessing()
{
//related operations
}
}
I am not going to repeat Open-close, DI, or other principals. It is already discussed. I would look at something like this, or even alternatively use Extensions to setup the value.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// old updated
public class Element
{
public Element(string msg) { Message = msg; }
public string Message;
}
public class XYZ { }
public class ABC { }
// new
public interface IDoesSomething
{
void SetResult();
}
// create 2 different wrappers
public class ValidationElementWrapper : IDoesSomething
{
public ValidationElementWrapper(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public void SetResult()
{
Console.WriteLine("This is " + Element.Message);
// Do nothing
}
}
public class ValidationElementWrapper2 : IDoesSomething
{
public ValidationElementWrapper2(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public string AdditionalProperty { get; set; }
public void SetResult()
{
AdditionalProperty = "Set additional property on wrapper 2";
Console.WriteLine("This is " + Element.Message + " and it has additional property - " + AdditionalProperty);
}
}
// run your program
public class Program
{
public static void Main()
{
var list = new List<IDoesSomething>();
list.Add(new ValidationElementWrapper(new Element("Element 1")));
list.Add(new ValidationElementWrapper2(new Element("Element 2")));
list.ForEach(item => item.SetResult());
}
}
Output
This is Element 1
This is Element 2 and it has additional property - Set additional property on wrapper 2
Alternatively, you can start with more basic class and then keep extending it
public class ValidationElementWrapper : IDoesSomething
{
public ValidationElementWrapper(Element el)
{
Element = el;
}
public Element Element { get; private set; }
public XYZ Location {get; set;}
public virtual void SetResult() // <--- virtual
{
// Do nothing
Console.WriteLine("This is " + Element.Message);
}
}
public class ValidationElementWrapper2 : ValidationElementWrapper // <-- inheritnce
{
public ValidationElementWrapper2(Element el) : base(el)
{
}
public XYZ Location {get; set;}
public string AdditionalProperty { get; set; }
public override void SetResult() // <--- override
{
AdditionalProperty = "Set additional property on wrapper 2";
Console.WriteLine("This is " + Element.Message + " and it has additional property - " + AdditionalProperty);
}
}
Result will be the same
This is class design question.
I have main abstract class
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestriction<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestriction<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestriction<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
BlockRule rule=new BlockRule();
TimeRestriction t=new TimeRestriction();
AgeRestriction a=new AgeRestriction();
rule.Restrictions.Add(t);
rule.Restrictions.Add(a);
I have to use non-generic Interface IRestriction just to avoid specifying generic type T in main abstract class. I'm very new to generics. Can some one let me know how to better design this thing?
Your approach is typical (for example, IEnumerable<T> implements IEnumerable like this). If you want to provide maximum utility to consumers of your code, it would be nice to provide a non-generic accessor on the non-generic interface, then hide it in the generic implementation. For example:
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions { get; set; }
}
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T:struct
{
// hide IRestriction.Limit
new T Limit {get;}
}
public abstract class RestrictionBase<T> : IRestriction<T>
where T:struct
{
// explicit implementation
object IRestriction.Limit
{
get { return Limit; }
}
// override when required
public virtual T Limit { get; set; }
}
public class TimeRestriction : RestrictionBase<TimeSpan>
{
}
public class AgeRestriction : RestrictionBase<TimeSpan>
{
}
public class BlockRule : AbstractBlockRule
{
public override List<IRestriction> Restrictions { get; set; }
}
I also showed using a base restriction class here, but it is not required.
The runtime treats IRestriction<TimeSpan> and IRestriction<int> as different distinct classes (they even have their own set of static variables). In your case the only classes common to both IRestriction<TimeSpan> and IRestriction<int> in the inheritance hierarchy are IRestriction and object.
So indeed, having a list of IRestriction is the only sensible way to go.
As a side note: you have a property Limit in there that you might want to access regardless of whether you're dealing with an IRestriction<TimeSpan> or IRestriction<int>. What I would do in this case is to define another property object Limit { get; } on IRestriction, and hide it in the actual implementation. Like this:
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T : struct
{
new T Limit { get; set; }
}
public class TimeRestriction : IRestriction<TimeSpan>
{
public TimeSpan Limit { get; set; }
// Explicit interface member:
// This is hidden from IntelliSense
// unless you cast to IRestriction.
object IRestriction.Limit
{
get
{
// Note: boxing happens here.
return (object)Limit;
}
}
}
This way you can access Limit as object on all your IRestriction when you don't care what type it is. For example:
foreach(IRestriction restriction in this.Restrictions)
{
Console.WriteLine(restriction.Limit);
}
Interfaces are contracts that need to be followed by the entity that implements the contract.
You have created two contract with the same name IRestriction
As far as I can see, what you are basically may need is a flag for classes that can be restricted, which should implement the IRestriction non-generic interface.
The second interface seems to be restrictable objects that also contain a limit property.
Hence the definition of the second IRestriction interface can be ILimitRestriction or whatever name suits your business needs.
Hence ILimitRestriction can inherit from IRestriction which would mark classes inheriting ILimitRestriction still objects of IRestriction
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestrictionWithLimit<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestrictionWithLimit<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestrictionWithLimit<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
I have the following builder/factory which abstracts a serializeable model from a class.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
}
}
And I have a concrete implementation of IFooModel like so:
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
}
public class ConcreteFooModel : IFooModel
{
public string AbstractedData1 { get; set; }
public string AbstractedData2 { get; set; }
public int AbstractedData3 { get; set; }
public bool ExtraData1 { get; set; }
}
Now arises the issue, I am struggling to find a way to not reference any concrete implementations in my builder/factory method, e.g.
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
var model = new ConcreteFooModel(someClass.data1, someClass.data1); // Aaargh
}
}
Something about this code is smelly to me, perhaps this is the only way, but I don't like the idea of being forced into referencing the concrete implementation to instantiate the data class, IFooModel.
This gets more complex if I now introduce another data holder interface into the IFooModel
public interface IFooModel
{
string AbstractedData1 { get; }
string AbstractedData2 { get; }
int AbstractedData3 { get; }
IBarData BarData { get; }
}
public interface IBarData
{
// some data in here
}
Forcing me then to create another concrete reference for the nested interface
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
Is there a better way to do this while still sticking to the SOLID principle and IoC?
What's important is to look at this from the perspective of the class that depends on IFooModel That's probably the first place where you want to prevent coupling.
You can accomplish that by injecting the factory into the class that needs it, like this:
public class NeedsFooFactory
{
private readonly IFooBarFactory _factory;
public NeedsFooFactory(IFooBarFactory fooBarFactory)
{
_factory = factory;
}
public void WhatEverThisClassDoes(IFoo foo)
{
var fooBar = _factory.Create(foo);
// Do something
}
}
Now the class that depends on the factory is decoupled from any implementation. You can substitute or mock another implementation of the factory that returns a different implementation of IFooModel.
Something to stop and think about at this point: Do you need an abstraction for ConcreteFooModel at all? If it's just a class that holds data then maybe you don't.
Getting back to the factory: Now that you can replace the factory with any implementation, this becomes less of a concern:
public class FooBarFactory : IFooBarFactory
{
public IFooModel Create(IFoo someClass)
{
// some complex model building code here
IBarData barData = new ConcreteBarData();
IFooModel model = new ConcreteFooModel(someClass.data1, someClass.data1, barData);
}
}
This implementation of the factory returns a specific concrete implementation of IFooModel. Is that bad? At some level classes are going to deal with concrete classes. In this case I think it's okay because this factory is doing what it's supposed to do. You don't have to worry that it's coupled to ConcreteFooModel. If you want a class that returns a different implementation you could create a different implementation of IFooBarFactory that returns a different implementation of IFooModel.
Again, this becomes even less of a concern if you question whether you need an abstraction for your foo model. Quite possibly the concrete class is all you need, and what matters is that you can have different implementations of the factory that populates it.
If I have the following Interface structure;
public interface IPaymentTypeBase
{
void PayNow();
double Amount { get; set; }
}
public interface IPaymentTypePayPal : IPaymentTypeBase
{
string UserName { get; set; }
string Password { get; set; }
}
public interface IPaymentMethod<T>
{
}
Then I have the following classes;
public class PaymentTypePayPal : IPaymentTypePayPal
{
public string UserName { get; set; }
public string Password { get; set; }
public void PayNow()
{
throw new NotImplementedException();
}
}
public class PaymentMethod<T> : IPaymentMethod<T> where T : IPaymentTypeBase
{
}
Then in my web application I have this;
IPaymentMethod<IPaymentTypePayPal> payer = (IPaymentMethod<IPaymentTypePayPal>) new PaymentMethod<PaymentTypePayPal>();
I'd now like to call payer.PayNow(); but I'm just getting lost in interfaces etc and can't seem to make this work.
I believe this is a simple thing but am just missing the point entierly.
Can anyone help?
Edit
The intention here is to have a set of interface such as PayPal, Voucher, CreditCard all of which do their own payment gateway type of stuff.
So I'd like to instantiate a class that takes the Payment Type as an interface and call that interfaces PayNow method.
payer is of type IPaymentMethod<IPaymentTypePayPal>.
But IPaymentMethod<T> is defined as
public interface IPaymentMethod<T>
{
}
Therefore, it has no methods and you can't call PayNow() on it.
The same is true for PaymentMethod<T>, so you can't call any method on an instance of PaymentMethod<PaymentTypePaypal> either.
Maybe you can explain a little more what your intention is.
I am not quite sure of why you are using that PaymentMethod class... But why cant you modify the interface IPaymentMethod to something like :
public interface IPaymentMethod<T> : IPaymentTypeBase
so that U can call the patNow method??
Personally, I'd use classes rather than interfaces whenever inheritance is involved. Also, in this case you've got more indirection than you probably need. If you model Payment as an abstract base class (with PayNow() and Amount) and PayPalPayment as the subclass, just instantiate the proper subclass from a factory and you're set, with all the flexibility you'd have with your approach, yet easier to understand and maintain, I think. (not really knowing all of the other requirements of your application)
I have a scenario where I have a bunch of jobs that I am scheduling to run at various times, the jobs themselves are being handled generically already which is great. And I have an abstract BaseJob class that they all inherit from that I use for common things (like the jobPK, startTime, exception logging, reporting, etc). But beyond that the jobs are very different, they have different properties and data associated with them that is entriely specific to them (I call these proprties JobDetails). So for example:
JobDetails for Job1
-customerId int
-cost double
-sku string
-userDefinedProperties SomeCustomObjectType
JobDetails for Job2
-name string
-executionDate DateTime
-otherProperties SomeOtherCustomObjectType
In the base class I would like to be able to store a reference to these JobDetails in as generic a fashion as possible (so in other words I don't want to just store it as object) to minimize the overhead for boxing/unboxing. Then I want to have the BaseJob class handle a lot of the common functionality that is needed for the app, so for example, if a job fails, I want to save its JobDetails to the database so that it can be restarted, I also want to log any errors that may have occured to a given job. For this I need to be able to extract those JobDetails and make use of them.
It seems like I need to make use of .NET generics and have a class of generic properties that I can stuff anything into and not have to worry about typing. What's the best way to handle this and make it efficient and flexible?
I hope that is clear, thanks for the help
You can make the JobDetails implement an interface and let have BaseJob have an abstract reference to it. Then in the actual jobs you implement the abstract JobDetails with the implementation you want. Then let the JobDetails interface define the methods BaseJob needs to work with. This is a slight variation on the Template Method design pattern. It would look something like this:
public interface IJobDetails {
void DoSomeWork();
}
public abstract BaseJob {
protected abstract IJobDetails JobDetails { get; set; }
public ExecuteJob {
//execute the job
JobDetails.DoSomeWork();
}
}
public Job1 : BaseJob {
public Job1() {
JobDetails = new ConcreteJobDetails();
}
protected override IJobDetails JobDetails { get; set; }
}
How about something like...
public abstract class JobBase<TDetails>
{
private TDetails details;
protected TDetails Details
{
get
{
if (details == null)
{
this.details = this.LoadDetails();
}
return this.details;
}
}
protected virtual TDetails LoadDetails()
{
// Some kind of deserialization of TDetails from your DB storage.
}
}
public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
public class ExampleJobDetails
{
public string ExampleProperty { get; set; }
public int AnotherProperty { get; set; }
}
}
You'd either want to have tables for each type used as TDetails or one big Key/Value based table for all of them. There are pros/cons to both. If you are super paranoid about boxing, there's no reason why TDetails can't be constrained to be a struct, too.
Edit: Got it backwards, you want to save the details on a failure. How about...
public abstract class JobBase<TDetails>
{
protected TDetails Details { get; private set; }
public JobBase()
{
this.Details = this.CreateDetails();
}
protected abstract TDetails CreateDetails();
protected void SaveDetails()
{
// Generic save to database.
}
}
public class ExampleJob : JobBase<ExampleJob.ExampleJobDetails>
{
public class ExampleJobDetails
{
public string ExampleProperty { get; set; }
public int AnotherProperty { get; set; }
}
protected override ExampleJobDetails CreateDetails()
{
return new ExampleJobDetails() { ExampleProperty = "Hi.", AnotherProperty = 1 };
}
}