Events Part 1 - Food for thought

Events

Event - a notification of a an occurrence or incidence, in programming terms, almost always in the past. Events are not always intuitive or easy to follow since they jump out of the natural control flow.
If we consider approaches to extend functionality without uglifying your class immediate thought goes to Dependency Injection. Whether it is a service or a Decorator, they now become the dependencies of your class, albeit through Inversion of Control. I am not saying this is bad, but raising events do not get a fair consideration.

Yet in so many cases they present as a great choice to extend functionality by reacting to them and even pass data out through to consuming clients. Yes, they can serve as a great vehicle to send data out. If you consider a method which returns void, but raises an event, then even though returning void is able to communicate or send out data through events. Neat.

Here I would be discussing on how to leverage events and improve code instead of delving into semantics of events and delegates in the DotNet framework. I intend this post to serves as a food for thought on using events to decouple behaviour.
Events enable loose coupling and promote separation of concerns. You can delegate (no pun intended) all external processing to the event handlers such as logging, notifications or calls to other services. The event could have multiple subscribers to it. It is a good way to update a subject’s dependents. As you can see, events need not be restricted to UI programming, but are also equally suitable for business components.
Let is consider a product domain. I’ll keep the domain logic simple and mundane so that we can focus on events and its usage. We wish to raise an event for each new product that gets added. The handlers(subscribers) who are interested in this event can then react to this.

Product(Subject)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class ProductSync
{
public event EventHandler<ProductSyncEventArgs> Saved;

// simulate data store
private readonly IDictionary<string, ProductSync> _productRepository;

public ProductSync()
{
_productRepository = new Dictionary<string, ProductSync>();
}

public string Name { get; set; }

public int Quantity { get; set; }

public void Add(string name, int quantity)
{
if (_productRepository.ContainsKey(name))
{
_productRepository[name].Quantity = quantity;
Console.WriteLine("Thread# {2}: {0} quantity updated to {1}",
name, quantity, Thread.CurrentThread.ManagedThreadId);
// no event will be raised here
return;
}
var p = new ProductSync() { Name = name, Quantity = quantity };
_productRepository.Add(name, p);
Console.WriteLine("Thread# {1}: New Product added - {0} ",
name, Thread.CurrentThread.ManagedThreadId);
OnSaved(p); // event raised
Console.WriteLine("Thread# {1}: Completed add for {0}",
name, Thread.CurrentThread.ManagedThreadId);
}

protected virtual void OnSaved(ProductSync p)
{
// check if we have any handlers listening
// and call them. Below is a short hand to do that.
(Saved as EventHandler<ProductSyncEventArgs>)?.Invoke(this, new ProductSyncEventArgs(p));
}
}

public class ProductSyncEventArgs : EventArgs
{
public ProductSyncEventArgs(ProductSync product)
{
Product = product;
}
public ProductSync Product { get; private set; }
}

I have deliberately appended Sync to the name. This is to highlight that event handlers subscribing to an event are invoked synchronously. The execution path does jump from one method to another, but the calls are blocking. I have included the thread id to show where the publishers and the subscribers are executing. This is important so that we do not have any misleading assumptions since the execution flow passes to the handlers. We also have a class ProductSyncEventArgs which inherits from EventArgs. This is a standard approach to pass arguments through events within DotNet.

Let us create a few subscribers or event handlers which need to do some work when event is raised.

Handlers (Subscribers)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class NotifyHandler
{
readonly ConsoleWriter cw;
public NotifyHandler()
{
cw = new ConsoleWriter();
}
public void SendMail(object source, ProductSyncEventArgs e)
{
Thread.Sleep(1000);
cw.Write("Thread# {1}: Sending email for product {0}",
ConsoleColor.Red, e.Product.Name,
Thread.CurrentThread.ManagedThreadId.ToString());
}
}

public class ExternalCallHandler
{
readonly ConsoleWriter cw;
public ExternalCallHandler()
{
cw = new ConsoleWriter();
}
public void DoCall(object source, ProductSyncEventArgs e)
{
Thread.Sleep(1000);
cw.Write("Thread# {1}: New note added for {0}",
ConsoleColor.Green, e.Product.Name,
Thread.CurrentThread.ManagedThreadId.ToString());
}
}

public class QuantityAuditHandler
{
readonly ConsoleWriter cw;
public QuantityAuditHandler()
{
cw = new ConsoleWriter();
}
public void Audit(object source, ProductSyncEventArgs e)
{
Thread.Sleep(1000);
cw.Write("Thread# {2}: Auditing for {1}. Quantity: {0}",
ConsoleColor.Yellow, e.Product.Quantity.ToString(), e.Product.Name,
Thread.CurrentThread.ManagedThreadId.ToString());
}
}

//helper to colour code console outputs
public class ConsoleWriter
{
public void Write(string message, ConsoleColor colour, params string[] args)
{
Console.ForegroundColor = colour;
Console.WriteLine(message, args);
Console.ResetColor();
}
}

The implementations are self-explanatory. I have added Thread.Sleep to simulate a load and helper class to output colour coded text to indicate some behaviour.

Application (Client)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Program
{
static void Main(string[] args)
{
var handler1 = new NotifyHandler();
var handler2 = new ExternalCallHandler();
var handler3 = new QuantityAuditHandler();

var product = new ProductSync();
// registering handlers
product.Saved += handler1.SendMail;
product.Saved += handler2.DoCall;
product.Saved += handler3.Audit;

product.Add("Cadbury classic", 10);
product.Add("Lindt Dark 80%", 10);
product.Add("Mars", 10);
product.Add("Cadbury classic", 10);
// unregistering handlers
product.Saved -= handler1.SendMail;
product.Saved -= handler2.DoCall;
product.Saved -= handler3.Audit;
}

When you run the program you get the below output. It clearly shows the synchronous execution and how the Add call is blocked until all the handlers have not returned.
Program output

When a product is now added there can be other actions executed without having to inject external dependencies to the Product class. I would however like to point out there are a few draw backs in implementing events this way. Astute readers would have already realised that what we have seen is DotNet’s inbuilt implementation of Observer pattern and most of these drawbacks are inherit to Observer pattern.

  • Multiple subscribers and publishers make it difficult to maintain and understand code.
  • Subscriber and publishers need to know each other. This tight coupling will not allow each to vary independently.
  • The publisher holds strong references of each observer. This might create memory leaks when the subscriber does not de-register themselves.

Here I would not go into addressing each of these issues, but these could be solved using Mediator pattern or Event Aggregate pattern. Again a warning, both these patterns at first glance might seem interchangeable or have the same intent, but they are not. Mediator helps in communicating between unrelated objects, which require co-ordinations. It is not mandatory to use Event type with in Mediator. You would see behaviour inside Mediator. Event Aggregators as the name suggests deal only in maintaining subscriptions and publishing of events. Once again it need not be done using Event type. You can also manage the references of subscribers to avoid memory leaks. Of course all this would mean more work upfront.
Well, like I had mentioned, this post was supposed to be a food for thought and use of events in modelling business logic.
In a continuing post I’ll explore how we can call the event handlers asynchronously.

Do let me know your thoughts through comments on how you have used events in your business layers?

Entity Framework stumps SQL performance by defaulting to Unicode

The other day I was working on building a POC which involved a legacy database. I decided to use code first’s fluent API to map out the configuration since the database was pretty complex and I wanted to control how EF sees it.

I always have SQL profiler open when programming EF just to make sure EF is doing the right thing. With EF6 onwards you could also use context.Database.Log to review what EF does underneath.

When I ran my application, I noticed a very visible lag in performance. The table I was working on was very large, but the query was returning only one row, so the impact really stood out. But I knew that the query would not take that long to execute otherwise. I looked at the query in the profiler and at first glance it looked normal. The query was as simple as it could be. I copied it and ran it under query analyser. The query once again took perceivably longer time to finish. This told me it was not EF alone responsible. Looked at the execution plan, it did not look normal. There was an index scan instead of seek and a lot of parallelism thrown in. Then I took a closer look at the query plan and voila the reason for the slow performance became obvious.

Entity Framework defaults to Unicode. This is very easy to overlook and under certain EF strategies and configurations it can really hit your SQL performance. Note, this has nothing to do with EF itself, but how SQL server prepares and executes the query provided by EF.

Let me illustrate with an example.
Below is my sample database. Product with many sales.
Database diagram

Below is how the mapping is defined.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Sale> Sales { get; set; }
}

public class Sale
{
public int Id { get; set; }
public int ProdId { get; set; }
public DateTime SaleDate { get; set; }
public virtual Product Product { get; set; }
}

public class ProductContext : DbContext
{
public ProductContext()
: base("TestDb")
{
Database.SetInitializer<ProductContext>(null);
}

public DbSet<Product> Products { get; set; }

public DbSet<Sale> Sales { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Product>().HasKey(p => p.Id)
.Property(p => p.Id)
.HasColumnName("ProdId")
.HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations
.Schema.DatabaseGeneratedOption.Identity);

modelBuilder.Entity<Product>()
.HasMany(s => s.Sales)
.WithOptional();

modelBuilder.Entity<Sale>().HasKey(s => s.Id)
.Property(s => s.Id)
.HasColumnName("SaleId")
.HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations
.Schema.DatabaseGeneratedOption.Identity);

modelBuilder.Entity<Sale>()
.Property(s => s.ProdId)
.HasColumnName("ProdId");

modelBuilder.Entity<Sale>()
.HasRequired(p => p.Product)
.WithMany(s => s.Sales)
.HasForeignKey(s => s.ProdId);
}
}

Below is how EF has interpreted the mapping.
EF model

Let us query for product by name.

1
var prods = prodContext.Products.Where(p => p.Name == "p3").ToList();

EF generates the below query.

1
2
3
SELECT [Extent1].[ProdId] AS [ProdId], [Extent1].[Name] AS [Name]
FROM [dbo].[Products] AS [Extent1]
WHERE N'p3' = [Extent1].[Name]

Pay attention to the Unicode conversion against the search value(N‘p3’). Below is the query plan.
Query plan

Notice how SQL is converting each row to Unicode before the search. This is what is killing your queries performance.
The fix is simple. Just let EF know that the column you are mapping to is not Unicode or is VARCHAR. This will allow EF to issue queries without the conversion.
Add mapping details for the Name property instead of mapping through convention. Specify either Not Unicode or the column type.

1
2
3
4
modelBuilder.Entity<Product>()
.Property(p => p.Name)
.IsUnicode(false);
//.HasColumnType("varchar");

If you approach using model first or code first without an existing database, you would not get into this problem since EF would create the database for you. This is also true if you reverse engineer your database to get your edmx generated. The tool would include the correct datatypes while mapping.

Now this should help me remember and hopefully help others too from stumbling.

Dependency Injection of Custom Claim Authorisation Manager

Claims

Authorisation is one of the most intertwined aspect in an application. We find it the most difficult part to isolate its implementations from rest of the logic. We can overcome partly syntactically through declarative sugar, but for more complex evaluations we might have to go inline. But the application still needs to continue checking the validity of the user.

The best thing that happened in security since .NET version 4.5 is that Claims became the base for all identity based security and with it we also saw ways through which we could externalise the authorisation logic (and also building of claims). A claim is statement or declaration made about oneself or others. When a user tries to claim access to any resource, the authorisation process assess if they trust the issuer of the claim and evaluates the claim.

In claim based authorisation the applications need not authenticate individuals and find out about the user. It is presented with claims by the user and the application just uses it to determine if they indeed have the right claim to continue. Now the application is undisturbed (decoupled) by the ever changing roles of a user or whether it has to accommodate any changed roles. As long as the user presents it with the right claims they get access.

Using claims not just simplifies authorisation, but you can use it to add other important facts about the user. During authentication, we could query multiple systems or specific sources which the application is more interested in and build the claim for the user. These could be email addresses, roles, position, mode of transport, dietary preferences anything which makes sense and need to share that information with applications. You can already see if used correctly how it would make authorisation and personalisation mush more easier in applications.

Enough with the introductions already! Windows Identity Foundation has now been merged with .NET Framework and we have access to default implementations of ClaimsAuthorizationManager. We can override this programmatically by using IdentityConfiguration or through application configuration file.

Through configuration:

1
2
3
4
5
<system.identityModel>
<identityConfiguration>
<claimsAuthorizationManager type="CustomAuthorisationManager"/>
</identityConfiguration>
</system.identityModel>

One limitation which it presents is that the custom type reference which we provide through configuration must have a 0 argument constructor. Which means we cannot specify any dependencies through the constructor.

This can however be overcome through code. We can register for the event FederationConfigurationCreated and when the FederationConfiguration is initialised, this event is raised where we can then modify the configuration to assign our own ClaimsAuthorizationManager.

Through code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
namespace ClaimsAwareApp
{
class App
{
static void Main(string[] args)
{
FederatedAuthentication.FederationConfigurationCreated +=
FederatedAuthentication_FederationConfigurationCreated;

//declarative
DoAction();

// inline
var cuthmgr = FederatedAuthentication.FederationConfiguration
.IdentityConfiguration.ClaimsAuthorizationManager;
var authContext =
new AuthorizationContext(ClaimsPrincipal.Current, "SomeResource", "Execute");
if (cuthmgr.CheckAccess(authContext))
Console.WriteLine("DoAction");
}

[ClaimsPrincipalPermission(
SecurityAction.Demand,
Operation = "Execute",
Resource = "SomeResource")]
static void DoAction()
{

}

private static void FederatedAuthentication_FederationConfigurationCreated(object sender,
FederationConfigurationCreatedEventArgs e)
{
DependencyFactory factory = new DependencyFactory();
e.FederationConfiguration.IdentityConfiguration.ClaimsAuthorizationManager =
new CustomClaimAuthorisation(factory);
//e.FederationConfiguration.IdentityConfiguration.ClaimsAuthenticationManager
// = new ClaimsAuthenticationManager();
}
}

class CustomClaimAuthorisation : ClaimsAuthorizationManager
{
private readonly DependencyFactory factory;
public CustomClaimAuthorisation(DependencyFactory factory)
{
this.factory = factory;
}

public override bool CheckAccess(AuthorizationContext context)
{
// Get instance from factory
using (var store = factory.GetStore())
{
// Do your authorisation
return base.CheckAccess(context);
}
}
}
class DependencyFactory
{
public MyStore GetStore()
{
return new MyStore();
}
}

class MyStore : IDisposable
{
public void Dispose()
{
// clean up
}
}
}

Few points to note!

You need to have system.identityModel in your configSections of your configuration file.

1
2
3
4
5
6
7
8
<configuration>
<configSections>
<section name="system.identityModel"
type="System.IdentityModel.Configuration.SystemIdentityModelSection,
System.IdentityModel, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=B77A5C561934E089" />
</configSections>
</configuration>

Without the above entry you would run into the below exception.

Message=ID7027: Could not load the identity configuration because no <system.identityModel> configuration section was found.

I think this config section is mandatory to get access to instance of FederationConfiguration. I anyway have not found a work around for this.

Also note that FederationConfiguration is created as a singleton and you would always get the same instance of ClaimsAuthorizationManager or ClaimsAuthenticationManager. So take care how you manage the lifetime of the objects which you inject inside of these instances. If you need to dispose them after each call, I recommend inject Factory instance instead of the actual concrete instance. This way you can dispose of the concretes and have the factory provide you with a new instance on each call to CheckAccess in the case of authorisation.

Of course for a web application, one should register the FederationConfigurationCreated event under global.asax App start.

Practical Patterns: Refactoring with Decorator Design Pattern

This post is the second in the series of Design Patterns. You may refer to the earlier article here Practical Patterns: Refactoring with Bridge Design Pattern

One cannot always start by applying design patterns with a new or greenfield project. Majority of the times we are working on existing or brownfield projects. We should be able to identify how the requirement can be retrofit into an existing code while retaining/enhancing maintainability and not adding any technical debts.
Earlier we had observed how through Bridge design pattern we were able to structurally separate the classes so they could be extended independently. Bridge pattern is applied at the class level.
Decorator design pattern is applied to an object and not to a class. Once again this is done through composition rather than inheritance.

Let us continue with the code from the previous article in seeing how we can manage new requirements through Decorator pattern.
We’ll naturally come across a few new requirements which I am going to conjure up. Firstly, the business requires each transaction to get audited. They also require notification to be sent for certain transactions. If we look at the requirements, we need to add behaviour to the existing implementations. They need to happen when a transaction is taking place.

Any class which needs to provide a transaction needs to implement ITransaction interface. This is implemented by Personal and Corporate classes. The auditing needs to be done when there is a deposit or withdrawal. We could introduce a base class which implements auditing. This class can be inherited by those who implement ITransaction. But, we would be exhausting the only inheritance allowed on these classes since the language supports only single inheritance. Even if we go ahead with this option, it would affect all the instances of the original class. What about the other requirement? How can we apply notifications to be sent from only certain instances? If and when we decide to remove notifications, how do we efficiently do it? We cannot selectively alter the behaviour of the objects during runtime through sub-classing. Also handling both the requirements in a base class would violate the Single Responsibility Principle(SRP).

Decorator pattern helps you in applying SRP while also selectively allowing us to add behaviour to objects and in any combination.
As many examples showcase, it is not always required or necessary to have an abstract class to implement decorator. But in many cases they might be convenient to have and we’ll see why. But for now we can do without one and have just the concrete decorators. All we need is to implement the interface which we wish to extend and also have a reference of the interfaces object internally. The decorators which we implement can be stacked in any order to add behaviour and repeated too.Decorator Pattern

The new changes are highlighted in blue.

AuditTransactionDecorator implements the first requirement of audting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class AuditTransactionDecorator : ITransaction
{
private readonly ITransaction transaction;
public AuditTransactionDecorator(ITransaction transaction)
{
this.transaction = transaction;
}

public void Deposit(decimal amount)
{
Console.WriteLine("Auditing amount BEFORE deposit transaction {0}", amount);
this.transaction.Deposit(amount);
Console.WriteLine("Auditing amount AFTER deposit transaction {0}", amount);
}

public decimal GetBalance()
{
return this.transaction.GetBalance();
}

public void Withdraw(decimal amount)
{
Console.WriteLine("Auditing amount BEFORE withdraw transaction {0}", amount);
this.transaction.Withdraw(amount);
Console.WriteLine("Auditing amount AFTER withdraw transaction {0}", amount);
}
}

NotifyTransactionDecorator implements the next requirement of notifying.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class NotifyTransactionDecorator : ITransaction
{
private readonly ITransaction transaction;
public NotifyTransactionDecorator(ITransaction transaction)
{
this.transaction = transaction;
}

public void Deposit(decimal amount)
{
this.transaction.Deposit(amount);
}

public decimal GetBalance()
{
return this.transaction.GetBalance();
}

public void Withdraw(decimal amount)
{
this.transaction.Withdraw(amount);
if (amount > 100)
{
Console.WriteLine("NOTIFY: The amount withdrawn has exceeded $100. The amount was {0}",
amount);
}
}
}

As you may notice, we are able to implement the new requirements in isolation and not having to modify the existing code.
In our AccountBase where we are creating the instance of type ITransaction, we can now decorate them with the new objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
abstract class AccountBase : IAccount
{
protected ITransaction transactionImp;
public AccountBase(string name, AccountType type)
{
Name = name;
switch (type)
{
case AccountType.Personal:
transactionImp = new AuditTransactionDecorator(
new Personal(1000));
break;
case AccountType.Corporate:
transactionImp = new NotifyTransactionDecorator(
new Corporate(5000));
break;
default:
throw new NotImplementedException("Unknown account type");
}
}

public abstract void Deposit(decimal amount);
public abstract void Withdraw(decimal amount);
public abstract decimal Balance { get; }
public string Name { get; private set; }
}

In line 10 and 14 we inject the original instance into the decorators. The decorators would now call the injected instances method along with its own. We could also stack the decorators together.

1
2
3
transactionImp = new AuditTransactionDecorator(
new NotifyTransactionDecorator(
new Corporate(5000)));

So when do we need an abstract class for decorators? Let’s take a look at our requirements again. For auditing requirement, we needed to decorate only the Deposit and Withdraw methods. For GetBalance we just had to forward the call to the internal reference of the interface’s concrete instance. For the notification, we just needed to add behaviour to the Withdraw method. Each requirement had a different set of methods being decorated. If we had to create multiple decorator classes targeting same methods, then a base class would have helped since it would provide a default implementation to methods which need to only forward the calls and allow us to implement only the targeted methods. This would also serve as a document indicating that classes derived from this base are decorators.
For example:

1
2
3
4
5
6
7
8
9
10
11
12
abstract class TransactionDecoratorBase : ITransaction
{
internal ITransaction transaction;

public abstract void Deposit(decimal amount);
public abstract void Withdraw(decimal amount);

public decimal GetBalance()
{
return transaction.GetBalance();
}
}

The implementation of auditing would look like this-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class AuditTransactionDecorator : TransactionDecoratorBase
{
public AuditTransactionDecorator(ITransaction transaction)
{
this.transaction = transaction;
}
public override void Deposit(decimal amount)
{
Console.WriteLine("Auditing amount BEFORE deposit transaction {0}", amount);
this.transaction.Deposit(amount);
Console.WriteLine("Auditing amount AFTER deposit transaction {0}", amount);
}
public override void Withdraw(decimal amount)
{
Console.WriteLine("Auditing amount BEFORE withdraw transaction {0}", amount);
this.transaction.Withdraw(amount);
Console.WriteLine("Auditing amount AFTER withdraw transaction {0}", amount);
}
}

Which takes us to the classic textbook diagram.Decorator pattern classic example

Practical Patterns: Refactoring with Bridge Design Pattern

You would have heard this before - the only thing constant is change. In software how do we prepare ourselves for change? Can we afford to over engineer in anticipation of change or do we create a big ball of mud as we continue to accommodate change?

Only in a perfect world would we be able to realise everything at one time and place. We need to be smart about how we design our software so that we can add/change features to it during its life. You Aren’t Gonna Need It (YAGNI) and SOLID would provide us with a good start so that refactoring need not be a pain. Refactoring is all in the mindset and often teams shy away from this practise.

In this start of my series, I’ll attempt to demonstrate on how we can use design patterns to refactor your existing code. Refactoring is a great approach even when you are working on a new piece of code and not just for modifying or enhancing existing software. It keeps your design light and simple.

Let us look at an overly simplified example of an account which facilitates in conducting a basic transaction. Let us also assume that this came in as your initial requirement and the client is implemented.Initial solution

IAccount is the abstraction which the clients would use.

1
2
3
4
5
6
7
interface IAccount
{
void Deposit(decimal amount);
void Withdraw(decimal amount);
decimal Balance { get; }
string Name { get; }
}

SavingAccount provides concrete implementation for IAccount.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class SavingAccount : IAccount
{
decimal _balance = 1000;

public SavingAccountLegacy(string name)
{
Name = name;
Console.WriteLine("Opened personal account with balance {0}", _balance);
}
public void Deposit(decimal amount)
{
_balance += amount;
Console.WriteLine("Deposited: {0} | New balance: {1}", amount, _balance);
}

public void Withdraw(decimal amount)
{
if (amount < _balance)
{
_balance -= amount;
Console.WriteLine("Widthdrawn: {0} | New balance: {1}", amount, _balance);
return;
}
Console.WriteLine("Could not withdraw. Current balance is {0}", _balance);
}

public decimal Balance
{
get { return _balance; }
}

public string Name
{
get;
private set;
}
}

The client is tightly bound to IAccount.

1
2
3
4
5
6
7
8
9
10
class Program
{
static void Main(string[] args)
{
IAccount account = new SavingAccount("A0001");
account.Withdraw(800);
account.Deposit(100);
account.Withdraw(400);
}
}

When you run the app you would see an output which indicates a set of transactions. These are from SavingAccount which portray some behaviour.

1
2
3
4
5
6
/*
Opened personal account with balance 1000
Widthdrawn: 800 | New balance: 200
Deposited: 100 | New balance: 300
Could not withdraw. Current balance is 300
*/

Down the line the inevitable happens and we have new requirements. There is a need to handle processing of transactions depending on whether the accounts are - personal or corporate. When you start seeing changes, it is time to sit up and consider whether it is good time to refactor your code. You anyway have to handle the requirement and there is a cue that you might see more change coming this way. Refactor now than struggle later.

One could just derive again from the existing class and provide the 2 new types. The client code is already bound tightly to the abstraction IAccount. Suppose a credit account is required which varies from savings and also requires to have the two flavours(personal & corporate) supported. As you meet new account types or variation thereof, there would be an explosion of classes due to inheritance. You could prevent this by having conditional checks in the existing classes for each account or transaction. But you would only make your code dirty and end up with technical debt. Here you should favour composition over inheritance while also retaining the abstraction.
Solution with inheritance

Introducing Bridge pattern here would allow you to separate the abstraction from its implementation. Let us dive into refactoring this code while leveraging this pattern.

Like the Bridge pattern states let us introduce another level of abstraction for the implementations. Make note that this abstraction is not exposed or known to the client and we’ll shortly see why this is important. You would continue to inherit IAccount to provide different account types, but their implementations would be abstracted away through ITransaction.

The new refactored diagram.Refactored with Bridge Pattern

The client still goes through the earlier interface IAccount which ensures that none of the refactoring impacts the client. The implementers of IAccount would have a concrete instance of ITransaction. This should be not be exposed to the client or be assigned by the client. This way the client is never bound to ITransaction and we can port the client to any underlying concrete implementation without recompiling it. Only the bridge itself and its implementer needs to be compiled. You can now add new type CreditAccount (varying abstraction), but still use the same implementations. Since you have decoupled your abstraction (IAccount) from the implementation (ITransaction), both can vary independently.

Abstraction for implementations.

1
2
3
4
5
6
interface ITransaction
{
void Deposit(decimal amount);
void Withdraw(decimal amount);
decimal GetBalance();
}

Note that this interface or base class can be different from the abstraction. They can provide a more finer interface.

Two flavours for an account implementation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
class Personal : ITransaction
{
private decimal _balance = 0;
public Personal(decimal balance)
{
_balance = balance;
Console.WriteLine("Opened personal account with balance {0}", balance);
}
public void Deposit(decimal amount)
{
_balance += amount;
Console.WriteLine("Deposited: {0} | New balance: {1}", amount, _balance);
}

public decimal GetBalance()
{
return _balance;
}

public void Withdraw(decimal amount)
{
if (amount < _balance)
{
_balance -= amount;
Console.WriteLine("Widthdrawn: {0} | New balance: {1}", amount, _balance);
return;
}
Console.WriteLine("Could not withdraw. Current balance is {0}", _balance);
}
}

class Corporate : ITransaction
{
private decimal _balance = 0;
private decimal _overdraft = 0;
const decimal overdraft_factor = 0.1m;
public Corporate(decimal balance)
{
_balance = balance;
Overdraft = _balance;
Console.WriteLine("Opened corporate account with balance {0}", balance);
Console.WriteLine("Overdraft stands at {0}", _overdraft);
}
public void Deposit(decimal amount)
{
_balance += amount;
Overdraft = _balance;
Console.WriteLine("Deposited: {0} | New balance: {1} | Overdraft: {2}",
amount, _balance, Overdraft);
}

public decimal GetBalance()
{
return _balance;
}

public void Withdraw(decimal amount)
{
if (amount < Overdraft)
{
_balance -= amount;
Overdraft = _balance;
Console.WriteLine("Widthdrawn: {0} | New balance: {1} | Overdraft: {2}",
amount, _balance, Overdraft);
return;
}
Console.WriteLine("Could not withdraw. Current overdraft limit {0}", Overdraft);
}

private decimal Overdraft
{
get
{ return _overdraft; }
set
{
_overdraft = Math.Abs(value) + (Math.Abs(value) * overdraft_factor);
}
}
}

Base class which selects the required implementer. This is not absolutely necessary, if we have setup a DI container, we could configure it to inject the concrete implementer directly in to the constructor of the abstraction. But the whole point is to not configure the concrete implementer by the client. Also one could have a factory method to return the required instance.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
abstract class AccountBase : IAccount
{
// this is protected and hidden from the client
protected ITransaction transactionImp;
public AccountBase(string name, AccountType type)
{
Name = name;
switch (type)
{
case AccountType.Personal:
transactionImp = new Personal(1000);
break;
case AccountType.Corporate:
transactionImp = new Corporate(5000);
break;
default:
throw new NotImplementedException("Unknown account type");
}
}

public abstract void Deposit(decimal amount);
public abstract void Withdraw(decimal amount);
public abstract decimal Balance { get; }
public string Name { get; private set; }

}

enum AccountType
{
Personal = 0,
Corporate
}

Refactored SavingAccount

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class SavingAccount : AccountBase
{
public SavingAccount(string name, AccountType type) : base(name, type)
{
}

public override void Deposit(decimal amount)
{
transactionImp.Deposit(amount);
}

public override void Withdraw(decimal amount)
{
transactionImp.Withdraw(amount);
}

public override decimal Balance
{
get { return transactionImp.GetBalance(); }
}

}

Finally, the client. Note it still uses the same interface. The client has not changed. You would need a way to decide which implementation to choose.

1
2
3
4
5
6
7
8
9
10
class Program
{
static void Main(string[] args)
{
IAccount account = new SavingAccount("A0001", AccountType.Personal);
account.Withdraw(800);
account.Deposit(100);
account.Withdraw(400);
}
}

Run the client and you see the same output which you had before refactoring.

1
2
3
4
5
6
/*
Opened personal account with balance 1000
Widthdrawn: 800 | New balance: 200
Deposited: 100 | New balance: 300
Could not withdraw. Current balance is 300
*/

But when you have a new interface, you can continue to use the same implementations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class CreditAccount : AccountBase
{
const decimal charge = 0.03m;

public CreditAccount(string name, AccountType type) : base(name, type)
{
}

public override void Deposit(decimal amount)
{
transactionImp.Deposit(amount);
}

public override void Withdraw(decimal amount)
{
amount = amount + (amount * charge);
Console.WriteLine("Credit withdraw surcharge levied: {0}", amount* charge);
transactionImp.Withdraw(amount);
}

public override decimal Balance
{
get { return transactionImp.GetBalance(); }
}
}

The client which uses the interface IAccount never changes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Program
{
static void Main(string[] args)
{
IAccount account = new SavingAccount("A0001", AccountType.Corporate);
account.Withdraw(800);
account.Deposit(100);
account.Withdraw(400);

Console.WriteLine("-----------------------------");
account = new CreditAccount("C2102", AccountType.Personal);
account.Withdraw(1000);
account.Deposit(1000);
account.Withdraw(5000);
account.Withdraw(200);

}
}

There is a lot of confusion between Bridge pattern and Strategy pattern. Both their implementations look similar, their UML representations look similar. You would have heard this before, but their intent is different. Now what the heck does that mean?
Strategy pattern provides a way to alter behaviour of the class(context) at runtime. The client decides which algorithm it needs to use based on some decision. The client uses the context which can take any instance of the strategy interface. The client is aware of both the context and the interface. The below client code blurs the distinction between Strategy and Bridge.

1
2
3
4
5
6
7
8
9
10
11
class Program
{
static void Main(string[] args)
{
IAccount account = new SavingAccount("A0001");
// client injects implementer instance to a property of type ITransaction.
account.Transaction = new Personal(1000);

account.Withdraw(800);
}
}

In Bridge pattern, the client is only aware of the abstraction and not the implementation. That was the reason you saw the instance being created internally. This pattern is used to keep your code maintainable structurally. If the client was injecting an instance of implementer, then it would not be a Bridge pattern since the client is changing the behaviour. Also Bridge provides two separate lines of abstractions which allow us to change either on a tangent.

Next Practical Patterns: Refactoring with Decorator Design Pattern