While
going through some basic stuff about design pattern, I come across the Bridge
design pattern & decided to implement it for Logging system.
My
take is to separate concern about What Is Being Logged & where is being Logged.
An
application can log errors as well as user actions too. Same time logging can
go to various places like Database, EventLog or a File.
Here
is Code for Classes that implement Logging system as Bridge Design pattern.
Code here is from a console application 'POALoggingAgent' with a class file 'LoggingAgent.cs' & implicitly created entry point i.e. Program.cs.
[LoggingAgent.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Data.SqlClient;
namespace POALoggingAgent
{
//Process
of Logging Should be Decoubled from Loggable Message
abstract class LogImplementor
{
public abstract bool Log(string Message);
}
//Let us
to change Logging Implementation at any latter moment when new requirement
arise
class LogAbstraction
{
protected LogImplementor Implementor;
protected string Message;
public LogAbstraction(string Msg)
{
Message = Msg;
}
//
Implementor
public LogImplementor LogImplementor
{
set
{
Implementor = value;
}
}
public virtual bool Log()
{
return Implementor.Log(Message);
}
}
//what
is to be logged an error,a user event,application event etc
class ErrorLogAbstraction : LogAbstraction
{
Exception LogggbleException;
public ErrorLogAbstraction(Exception exp):base(string.Empty)
{
LogggbleException = exp;
}
public override bool Log()
{
/*manipulate
exception object propeties to build */
Message = FormatMessage();
return Implementor.Log(Message);
}
public string FormatMessage()
{
//Do
Some work on LogggbleException to create formated message and set it to Message
inherited Variable
return "***" + LogggbleException .Message+ "***";
}
}
//initial
logging was on console
class ConsoleLogImplementor : LogImplementor
{
public override bool Log(string Message)
{
try
{
/*BEGIN
- Code To Log Message To Console*/
/*END - Code To Log Message To Console*/
//Place
Holder
Console.WriteLine("Class:ConsoleLogImplementor,Method:Log,Message:" + Message);
return true;
}
catch
{
return false;
}
}
}
//logging
to database is new requirement generated
class DbLogImplementor : LogImplementor
{
public override bool Log(string Message)
{
try
{
/*BEGIN
- Code To Log Message To DB*/
/*END - Code To Log Message To Db*/
//Place
Holder
Console.WriteLine("Class:DbLogImplementor,Method:Log,Message:" + Message);
return true;
}
catch
{
return false;
}
}
}
}
Calling above code from our console Application
[Program.cs]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace POALoggingAgent
{
class Program
{
static void Main(string[] args)
{
try
{
int i = 0;
int j = 1;
Console.WriteLine("Trying to
Divide 1 by 0,Output = " + Convert.ToString(j / i));
}
catch (Exception exp)
{
LogAbstraction LogAb = new ErrorLogAbstraction(exp);
// choose console Logging Implementation
LogAb.LogImplementor = new ConsoleLogImplementor();
LogAb.Log();
//
choose Database Logging Implementation
LogAb.LogImplementor = new DbLogImplementor();
LogAb.Log();
}
// Wait
for user
Console.ReadKey();
}
}
}
To be Frank, I am
not sure if Bridge Design Pattern is
suitable case for Logging system as there are Singleton & Command, Chain of
Responsibility & Subscriber- Publisher; that are often used with logging system.
Anyone who willing to help me to improve above design of so called Logging
system is more than welcomed!
No comments:
Post a Comment