In ESFramework design and implementation, the Null Object design mode is used in many places. The Null Object Mode means that an Object is provided to a specified type to replace the Null Object. Null Object provides "nothing" to hide details from its collaborators.
You can describe how to understand and apply this mode through an instance. In this section, we will discuss the message dispatcher, which uses the aforementioned logger and injects specific logger objects through attributes.
Private IEsfLogger esfLogger;
Public IEsfLogger EsfLogger
{
Set
{
This. esfLogger = value;
}
}
Now, if we use a logger to record logs in multiple places in the message dispatcher, we always need to write such a statement:
If (this. esfLogger! = Null)
{
This. esfLogger. Log (); // logs
}
That is to say, before using it, we must determine whether the reference of the logger is null. If it is not null, the Log method can be called. If a logger is called to record a large number of logs, every place is filled with code that determines whether the reference is empty. Is there any way to avoid all these judgment statements? Yes! That is, the Null Object design mode is used.
ESFramework provides the corresponding Null Object Type for each required component. These types of names are prefixed with "Empty. For example, the Null Object type corresponding to IEsfLogger is EmptyEsfLogger, and the Log method implemented by EmptyEsfLogger does not need to be implemented at all:
Public void Log (string errorType, string msg, string location, ErrorLevel)
{
// Do Nothing!
}
With EmptyEsfLogger, we can design the logger attributes of the message dispatcher as follows:
Private IEsfLogger esfLogger = new EmptyEsfLogger ();
Public IEsfLogger EsfLogger
{
Set
{
If (value! = Null)
{
This. esfLogger = value ?? New EmptyEsfLogger ();
}
}
}
First, set the default value of the esfLogger field to a Null Object. Second, each time the caller tries to set the EsfLogger attribute to null, a Null Object is also assigned to this field.
In this way, in the message distributor, we can easily directly use the logger without judging whether the reference is null, because in any case, it always points to a valid Object, even if the Object is a Null Object.
In addition to the common component assembly that can use the Null Object mode, there is also a very suitable scenario for using the Null Object mode, that is, "Event ". Do you still remember that every time we trigger an event, we need to determine whether it is empty. This is also a very trivial matter. We can still simplify it through the Null Object Mode. For example, an event is defined in a class:
Public event CbSimple SomeOneConnected;
In the class constructor, you can use Null Object to initialize it:
This. SomeOneConnected + = delegate {};
In this way, when an event is triggered, you do not need to judge whether it is null:
This. SomeOneConnected (); // you do not need to judge whether it is null to directly trigger the event.
Flexible use of the Null Object design mode can make our code more concise and refined.
Note: This article excerpted the self-published article "design, implementation and application of the. NET Communication Framework"