DMA Design Project - first submission

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
m
 
(4 intermediate revisions by one user not shown)
Line 13: Line 13:
 
But like all ideas it grew and expanded until it needed to:
 
But like all ideas it grew and expanded until it needed to:
  
  • Log items to any type of destination, including but not limited to, the Windows event log, a file, the debug or console window inside the Visual Studio IDE or memory.
+
* Log items to any type of destination, including but not limited to, the Windows event log, a file, the debug or console window inside the Visual Studio IDE or memory.
  • Filter what items are logged but with a filter that can be changed on the fly.
+
* Filter what items are logged but with a filter that can be changed on the fly.
  • Specify how each item is formatted before output.
+
* Specify how each item is formatted before output.
  • Log to multiple destinations using a single logger.
+
* Log to multiple destinations using a single logger.
  • ‘Roll over’ a log file based on date or file size or any other specified criteria.
+
* ‘Roll over’ a log file based on date or file size or any other specified criteria.
  • Allow the severity for each log entry to be specified.
+
* Allow the severity for each log entry to be specified.
  • Assign each item logged a category.
+
* Assign each item logged a category.
  • Log items to a XML file in an efficient manner.
+
* Log items to a XML file in an efficient manner.
  • Log any types of items, as long as it is a string or maybe an exception.
+
* Log any types of items, as long as it is a string or maybe an exception.
  
 
And behold it was good.
 
And behold it was good.
Line 32: Line 32:
 
There was much deep thought and gnashing of teeth in the above design which resulted in:
 
There was much deep thought and gnashing of teeth in the above design which resulted in:
  
  • It can only log strings, why would you need anything else.
+
* It can only log strings, why would you need anything else.
  • The loggers included in the design cover all known logging requirements, though it is possible, however unlikely, that others may be needed.
+
* The loggers included in the design cover all known logging requirements, though it is possible, however unlikely, that others may be needed.
  • The SplitFileLogger or RollingFileLogger classes have been cleverly designed using the decorator design pattern to allow a file logger to be wrapped many times.
+
* The SplitFileLogger or RollingFileLogger classes have been cleverly designed using the decorator design pattern to allow a file logger to be wrapped many times.
  • The rolling file logger cried out for the strategy design pattern for the roll over algorithm and so it was.
+
* The rolling file logger cried out for the strategy design pattern for the roll over algorithm and so it was.
  • Formatter classes are not responsible for the formatting of the entry text.
+
* Formatter classes are not responsible for the formatting of the entry text.
  • In order to save tedious coding when creating new logger classes the Logger class is an abstract class that contains all the common functionality between the different loggers, including helper functions around the filtering and formatting of items. This makes it much simpler to define new loggers and obeys the ‘Programming by difference’ and ‘Encapsulate that which varies’ principles.
+
* In order to save tedious coding when creating new logger classes the Logger class is an abstract class that contains all the common functionality between the different loggers, including helper functions around the filtering and formatting of items. This makes it much simpler to define new loggers and obeys the ‘Programming by difference’ and ‘Encapsulate that which varies’ principles.
  • The filter, formatting and rollover strategy classes are interfaces because the implementations between the different types for each can widely differ.
+
* The filter, formatting and rollover strategy classes are interfaces because the implementations between the different types for each can widely differ.
 +
 
 +
There are six different types of loggers defined:
 +
* NullLogger:  This logger logs items to the null device, i.e. does nothing.  Have not yet decided if it should still apply any filtering or just do nothing and always return true.
 +
* ConsoleLogger: This logger logs items to the console window in the Visual Studio IDE.
 +
* MemoryLogger: This logger stores the logged items in an internal collection which can be publicly accessed as a read-only copy.
 +
* CompositeLogger: This logger can contain any number of loggers.  Allows multiple logs to be logged to with a single call.
 +
* EventLogLogger: This logger logs items to the Windows Application Event Log.
 +
* FileLogger: This logger logs items to a file.
 +
* RollingFileLogger: This logger logs items to a file, where the file name is dynamic and is dependant on the original file name and the rollover strategy used.
 +
* SplitFileLogger: This logger logs items to two files: A data file where the items are logged to and a header file whose contents are fixed.
 +
 
 +
The SplitFileLogger class seems to be fairly strange class.  It was designed to allow efficient logging of items in a XML format by creating a header file that was a complete xml document that contained an entity pointing to the data file.  This allows items to be logged to the data file by simply appending new items to the end.  
  
 
== Just so you will know ==
 
== Just so you will know ==
Line 47: Line 59:
  
 
The name of interfaces will have an ‘I’ prefix which again follows the standard programming practices for.Net in general.
 
The name of interfaces will have an ‘I’ prefix which again follows the standard programming practices for.Net in general.
 +
 +
The design does not show any local variables for any of the classes but because of past experiences where parent classes required modifying to allow subclasses access to local variables I moved to specifying local variables as being protected.  Until recently I was unaware that was part of class versus object encapsulation.  However, after just recently being able to solve issues I encountered in implementing inheritance in C#, I am leaning towards using getters and setters for accessing and setting local variables.  This would mean implementing the setters as protected to allow subclasses the ability to update local variables.
  
 
== Greatest ever ==
 
== Greatest ever ==
  
 
Despite being the greatest piece of software design known to humankind there were some issues.  Not many but some.  A few were due to the design itself and the rest were due to the language the design was implemented using, i.e. C#.
 
Despite being the greatest piece of software design known to humankind there were some issues.  Not many but some.  A few were due to the design itself and the rest were due to the language the design was implemented using, i.e. C#.
  • It turned out just logging plain text did not cut the mustard.  Other data types need also to be logged, including exceptions.  Changing the design to employ generics allowed different data types to be logged without having to create logger classes for each different type.  This does mean however that a formatter class is needed per data type logged.
+
* It turned out just logging plain text did not cut the mustard.  Other data types need also to be logged, including exceptions.  Changing the design to employ generics allowed different data types to be logged without having to create logger classes for each different type.  This does mean however that a formatter class is needed per data type logged.
  • It also makes sense to be able to log items in a XML format, which means creating a new logger to log items as XML.
+
* It also makes sense to be able to log items in a XML format, which means creating a new logger to log items as XML.
  • During implementation testing in C# in .Net 4.0 it was discovered
+
* Under some circumstances it would be necessary to receive notifications when items were logged.  Initially this was implemented in the form of a decorator class that added observable functionality to any logger class.  However if this decorator class was wrapped around a logger class that extended the interface of the Logger class, such as the memory logger, then the extra functionality was no longer available.  So the design was changed to add observable functionality only to the memory logger class as that seemed the most logical place it would be required.
If there is a class A, which contained a method M and a second class B, that was a subclass of A that overrode method M, then whenever an instance of class B was passed through to any method as type A, calling M on the instance of B did not invoke the overridden M on B but actually called the M on the base class A.
+
This appeared to be part of a conspiracy to encourage the use of interfaces in .Net by Microsoft. So to fit in better with other designs it was changed to make more use of interfaces. In particular the file, rolling file and split file logger classes were changed to implement a new file logger interface to ensure that the correct method was called on the correct class.
+
  • Under some circumstances it would be necessary to receive notifications when items were logged.  Initially this was implemented in the form of a decorator class that added observable functionality to any logger class.  However if this decorator class was wrapped around a logger class that extended the interface of the Logger class, such as the memory logger, then the extra functionality was no longer available.  So the design was changed to add observable functionality only to the memory logger class as that seemed the most logical place it would be required.
+
  
 
== Perfection ==
 
== Perfection ==
Line 62: Line 73:
 
And thus perfection was at last achieved.
 
And thus perfection was at last achieved.
  
[[Image:DMA_LoggingFrameworkVersion2.png]]
+
[[Image:GenericLoggingFrameworkClassDiagram.png]]
  
  
 
== Just between you and me ==
 
== Just between you and me ==
  
A lot of changes that appear in the revised design are due to issues and complications found during a test implementation of the initial design, in particular the changes made around the file logger class and its subclasses.  The changes made to the file logger do work and are effective but they seem wrong, very wrong.  Smell bad even. It appears that some of issues with the design stem from the fact that C# uses class encapsulation and not object encapsulation and that desire on my part to reduce the amount of duplicated code by using abstract and derived classes. One example is the file logger class and its subclasses.  The file logger class has code to write items logged to a file and so the split file logger and rolling file logger classes extend the file logger class to make use of this code.  If those two classes did not extend the file logger class but just implemented the file logger interface then the design would be cleaner but most likely result in duplicated code.  
+
A lot of changes that appear in the revised design are due to issues and complications found during a test implementation of the initial design   
  
On the surface it seemed that the XML logger is just a subtype of a split file logger as the XML logger will create two files.  It was designed to allow efficient logging of items in a XML format but creating a header file that was a complete XML document that contained an entity pointing to the data file.  This allows items to be logged to the data file by simply appending new items at the end.  It does however smack a bit of ‘inheritance for implementation’ as the XML logger should not expose the full interface of the split file logger.  A better solution may be for the XML logger class to contain an instance of a split file logger.
+
On the surface it seemed that the XML logger is just a subtype of a split file logger as the XML logger will create two files.  It was designed to allow efficient logging of items in a XML format but creating a header file that was a complete XML document that contained an entity pointing to the data file.  This allows items to be logged to the data file by simply appending new items at the end.  It does however smack a bit of ‘inheritance for implementation’ as the XML logger should not expose the full interface of the split file logger.  A better solution is for the XML logger class to contain an instance of a split file logger.
  
 
== Finally ==
 
== Finally ==
  
 
The design above does not show all the classes that are expected to be included in the framework.  In particular there will be a collection of formatter classes for some common data types including strings and exceptions.
 
The design above does not show all the classes that are expected to be included in the framework.  In particular there will be a collection of formatter classes for some common data types including strings and exceptions.

Latest revision as of 21:06, 16 September 2010

Contents

Cosc427 Design Project 2010 - Darryl Anderson

In the beginning

In the beginning there was an idea, and like most good ideas it was simple.

DMA SimpleIdea.png

A logging system capable of logging any sort of data (as long as it was plain text) and to any destination.

New and improved

But like all ideas it grew and expanded until it needed to:

  • Log items to any type of destination, including but not limited to, the Windows event log, a file, the debug or console window inside the Visual Studio IDE or memory.
  • Filter what items are logged but with a filter that can be changed on the fly.
  • Specify how each item is formatted before output.
  • Log to multiple destinations using a single logger.
  • ‘Roll over’ a log file based on date or file size or any other specified criteria.
  • Allow the severity for each log entry to be specified.
  • Assign each item logged a category.
  • Log items to a XML file in an efficient manner.
  • Log any types of items, as long as it is a string or maybe an exception.

And behold it was good.

DMA LoggingFrameworkVersion1.png


In the making

There was much deep thought and gnashing of teeth in the above design which resulted in:

  • It can only log strings, why would you need anything else.
  • The loggers included in the design cover all known logging requirements, though it is possible, however unlikely, that others may be needed.
  • The SplitFileLogger or RollingFileLogger classes have been cleverly designed using the decorator design pattern to allow a file logger to be wrapped many times.
  • The rolling file logger cried out for the strategy design pattern for the roll over algorithm and so it was.
  • Formatter classes are not responsible for the formatting of the entry text.
  • In order to save tedious coding when creating new logger classes the Logger class is an abstract class that contains all the common functionality between the different loggers, including helper functions around the filtering and formatting of items. This makes it much simpler to define new loggers and obeys the ‘Programming by difference’ and ‘Encapsulate that which varies’ principles.
  • The filter, formatting and rollover strategy classes are interfaces because the implementations between the different types for each can widely differ.

There are six different types of loggers defined:

  • NullLogger: This logger logs items to the null device, i.e. does nothing. Have not yet decided if it should still apply any filtering or just do nothing and always return true.
  • ConsoleLogger: This logger logs items to the console window in the Visual Studio IDE.
  • MemoryLogger: This logger stores the logged items in an internal collection which can be publicly accessed as a read-only copy.
  • CompositeLogger: This logger can contain any number of loggers. Allows multiple logs to be logged to with a single call.
  • EventLogLogger: This logger logs items to the Windows Application Event Log.
  • FileLogger: This logger logs items to a file.
  • RollingFileLogger: This logger logs items to a file, where the file name is dynamic and is dependant on the original file name and the rollover strategy used.
  • SplitFileLogger: This logger logs items to two files: A data file where the items are logged to and a header file whose contents are fixed.

The SplitFileLogger class seems to be fairly strange class. It was designed to allow efficient logging of items in a XML format by creating a header file that was a complete xml document that contained an entity pointing to the data file. This allows items to be logged to the data file by simply appending new items to the end.

Just so you will know

This framework is part of a project to be written using C#, in .Net 4.0 and has a secondary goal of exploring the use of code contracts, prompted in part by the new inbuilt support for code contracts in .Net 4.0

Properties in the design will be shown with separate getters and setters. This is so that it can be easily seen which properties are read only, set only or have different access modifiers. However properties will be implemented using the inbuilt property mechanism in C# where the getter and setters for a property have a single name. This violates the Riel's heuristic ‘Command query separation’ but I believe it is acceptable because it follows the standard programming practices for .Net and it is obvious what code is calling the ‘getter’ and what is calling the ‘setter’.

The name of interfaces will have an ‘I’ prefix which again follows the standard programming practices for.Net in general.

The design does not show any local variables for any of the classes but because of past experiences where parent classes required modifying to allow subclasses access to local variables I moved to specifying local variables as being protected. Until recently I was unaware that was part of class versus object encapsulation. However, after just recently being able to solve issues I encountered in implementing inheritance in C#, I am leaning towards using getters and setters for accessing and setting local variables. This would mean implementing the setters as protected to allow subclasses the ability to update local variables.

Greatest ever

Despite being the greatest piece of software design known to humankind there were some issues. Not many but some. A few were due to the design itself and the rest were due to the language the design was implemented using, i.e. C#.

  • It turned out just logging plain text did not cut the mustard. Other data types need also to be logged, including exceptions. Changing the design to employ generics allowed different data types to be logged without having to create logger classes for each different type. This does mean however that a formatter class is needed per data type logged.
  • It also makes sense to be able to log items in a XML format, which means creating a new logger to log items as XML.
  • Under some circumstances it would be necessary to receive notifications when items were logged. Initially this was implemented in the form of a decorator class that added observable functionality to any logger class. However if this decorator class was wrapped around a logger class that extended the interface of the Logger class, such as the memory logger, then the extra functionality was no longer available. So the design was changed to add observable functionality only to the memory logger class as that seemed the most logical place it would be required.

Perfection

And thus perfection was at last achieved.

GenericLoggingFrameworkClassDiagram.png


Just between you and me

A lot of changes that appear in the revised design are due to issues and complications found during a test implementation of the initial design

On the surface it seemed that the XML logger is just a subtype of a split file logger as the XML logger will create two files. It was designed to allow efficient logging of items in a XML format but creating a header file that was a complete XML document that contained an entity pointing to the data file. This allows items to be logged to the data file by simply appending new items at the end. It does however smack a bit of ‘inheritance for implementation’ as the XML logger should not expose the full interface of the split file logger. A better solution is for the XML logger class to contain an instance of a split file logger.

Finally

The design above does not show all the classes that are expected to be included in the framework. In particular there will be a collection of formatter classes for some common data types including strings and exceptions.

Personal tools