- Interface contains declaration of methods, properties, events and indexers.
public interface ITaxCalculator
{
int Calculate();
}
Interface and Testability
- In order to unit test a class, we need to isolate it. This means: we need to assume that every other class in our application is working properly and see if the class under test is working as expected. But in below example, OrderProcessor class is depended on the ShippingCalculator class because of "CalculateShipping" method in "Process" method.
public class Shipment { public DateTime shippingdate; public object cost { get; set; } } public class Order { public Shipment Shipment; public bool IsShipped { get { return Shipment != null; }} public DateTime DatePlaced { get; set; } public float TotalProce { get; set; } } class Program { static void Main(string[] args) { var orderprocessor = new OrderProcessor(); var order = new Order { DatePlaced = DateTime.Now, TotalProce = 100f }; orderprocessor.Process(order); } } public class OrderProcessor { private readonly ShippingCalculator _shippingCalculator; public OrderProcessor() { _shippingCalculator = new ShippingCalculator(); } public void Process(Order order) { if (order.IsShipped) { throw new InvalidOperationException("The order already is shipped"); } order.Shipment = new Shipment {
//Depend on the ShippingCalculator class
cost = _shippingCalculator.CalculateShipping(order), shippingdate = DateTime.Now.AddDays(1) }; } } public class ShippingCalculator { public float CalculateShipping(Order order) { if (order.TotalProce > 30f) { return order.TotalProce * 0.01f; } return 0; } }
public class Shipment
{
public DateTime shippingdate;
public object cost { get; set; }
}
public class Order
{
public Shipment Shipment;
public bool IsShipped { get { return Shipment != null; }}
public DateTime DatePlaced { get; set; }
public float TotalProce { get; set; }
}
class Program
{
static void Main(string[] args)
{
var orderprocessor = new OrderProcessor(new ShippingCalculator());
var order = new Order { DatePlaced = DateTime.Now, TotalProce = 100f };
orderprocessor.Process(order);
Console.Read();
}
}
public class OrderProcessor
{
private readonly IShippingCalculator _shippingCalculator;
public OrderProcessor(IShippingCalculator calculator)
{
_shippingCalculator = calculator;
}
public void Process(Order order)
{
if (order.IsShipped)
{
throw new InvalidOperationException("The order already is shipped");
}
order.Shipment = new Shipment
{
cost = _shippingCalculator.CalculateShipping(order),
shippingdate = DateTime.Now.AddDays(1)
};
}
}
public interface IShippingCalculator
{
float CalculateShipping(Order order);
}
public class ShippingCalculator : IShippingCalculator
{
public float CalculateShipping(Order order)
{
if (order.TotalProce > 30f)
{
return order.TotalProce * 0.01f;
}
return 0;
}
}
Interfaces and Extensibility- We can use interfaces to change our application’s behaviour by “extending” its code(rather than changing the existing code).
- If a class is dependent on an interface, we can supply a different implementation of that interface at runtime. This way, the behaviour of the application changes without any impact on that class.
- For example, let’s assume our DbMigrator class is dependent on an ILoggerinterface. At runtime, we can supply a ConsoleLogger to log the messages on the console. Later, we may decide to log the messages in a file (or a database). We can simply create a new class that implements the ILogger interface and inject it into DbMigrator.
public interface ILogger
{
void LogInfo(string message);
void LogError(string message);
}
public class DBMigrator
{
private readonly ILogger _logger;
public DBMigrator(ILogger logger)
{
_logger = logger;
}
public void Migrate()
{
_logger.LogError("DBMigrating started at " + DateTime.Now);
_logger.LogInfo("DBMigrating ended at " + DateTime.Now);
}
}
public class ConsoleLogger : ILogger
{
public void LogError(string message)
{
Console.WriteLine(message);
}
public void LogInfo(string message)
{
Console.WriteLine(message);
}
}
public class FileLogger : ILogger
{
public void LogError(string message)
{
//Here should write the code to insert the log error in to file
Console.WriteLine(message);
}
public void LogInfo(string message)
{
//Here should write the code to insert the loginfo in to file
Console.WriteLine(message);
}
}
References : Udemy.com
No comments:
Post a Comment