1988년 Babara Liskov는 자신의 논문에서 “자식 클래스들은 부모 클래스의 인터페이스를 통해서 사용 가능해야 하고 사용자는 그 차이를 몰라야 한다” 라고 우김..
의미 – 상위 클래스가 사용되는 곳에는 하위 클래스가 사용될 수 있어야 한다.
아래는 에레에 대해서 로깅을 하는 예제코드 입니다.
아래코드는 간단하게 C#으로 되었습니다. ^^
public class ExceptionLogger
{
public void Log(Exception ex)
{
Console.WriteLine(“An exception has occurred.”);
Console.WriteLine(ex.ToString());
}
}
————————————————————————————————————————-
public class FileExceptionLogger
{
public void Log(Exception ex, string fileName)
{
using (StreamWriter sw = new StreamWriter(fileName))
{
sw.WriteLine(ex.ToString());
}
}
}
public class EmailExceptionLogger
{
public void Log(Exception ex, string server, string toAddress)
{
MailMessage msg = new MailMessage(“errors@testcompany.com”, toAddress);
msg.Subject = “An exception has occurred.”;
msg.Body = ex.ToString();
SmtpClient client = new SmtpClient(server);
client.Send(msg);
}
}
————————————————————————————————————————-
// 위의 화면, 파일, 이메일 로그에 대해서 개별적인 기능 제공에 대한 문제
public static void Main(string[] args)
{
ExceptionLogger log = new ExceptionLogger();
FileExceptionLogger fileLogger = new FileExceptionLogger();
EmailExceptionLogger emailLogger = new EmailExceptionLogger();
try
{
NestedException();
}
catch (Exception ex)
{
log.Log(ex);
fileLogger.Log(ex, “errors.log”);
emailLogger.Log(ex, “localhost”, “myemail@testcompany.com”);
}
}
————————————————————————————————————————-
// 위의 개별 클래스, 개별기능으로 인해서 로깅에 대한 모듈이 확장성이 없어지는 문제를 아래와 같이 해결할 수 있다는 내용입니다.public interface ExceptionLogger
{
public abstract void Log(Exception ex);
}
public class ConsoleExceptionLogger : ExceptionLogger
{
public void Log(Exception ex)
{
Console.WriteLine(“An exception has occurred.”);
Console.WriteLine(ex.ToString());
}
}
public class FileExceptionLogger : ExceptionLogger
{
public void Log(Exception ex)
{
// can’t really do anything without a filename
// just want to fill out the interface.
}
public void Log(Exception ex, string fileName)
{
using (StreamWriter sw = new StreamWriter(fileName))
{
sw.WriteLine(ex.ToString());
}
}
}
public class EmailExceptionLogger : ExceptionLogger
{
public void Log(Exception ex)
{
// see Log(Exception) on FileExceptionLogger
}
public void Log(Exception ex, string server, string toAddress)
{
MailMessage msg = new MailMessage(“errors@testcompany.com”, toAddress);
msg.Subject = “An exception has occurred.”;
msg.Body = ex.ToString();
SmtpClient client = new SmtpClient(server);
client.Send(msg);
}
}
————————————————————————————————————————-
// 위는 로깅에 대한 모듈이 확장성이 있지만 개별기능에 대해서 호출하는 문제를 아래와 같이 공통기능으로 뽑아서 공통 메쏘드를 호출할 수 있도록 해 주는 솔루션입니다.public class FileExceptionLogger : ExceptionLogger
{
private readonly string fileName;
public FileExceptionLogger(string file)
{
this.fileName = file;
}
public void Log(Exception ex)
{
using (StreamWriter sw = new StreamWriter(fileName))
{
sw.WriteLine(ex.ToString());
}
}
}
public class EmailExceptionLogger : ExceptionLogger
{
private readonly string server;
private readonly string toAddress;
public EmailExceptionLogger(string smtpServer, string to)
{
this.server = smtpServer;
this.toAddress = to;
}
public void Log(Exception ex)
{
MailMessage msg = new MailMessage(“errors@testcompany.com”, toAddress);
msg.Subject = “An exception has occurred.”;
msg.Body = ex.ToString();
SmtpClient client = new SmtpClient(server);
client.Send(msg);
}
}