Not all people need to know everything. Not all types must be public. For each type, the access level should be restricted as much as possible when the function is met. In addition, these access levels are often much less than you think. In a private type, all users can access the functions defined by this interface through a public interface.
Let's go back to the most fundamental situation: powerful tools and lazy developers. Vs.net is a great high-yield tool for them. I use vs.net or C # builder to easily develop all my projects, because it allows me to complete tasks faster. One of the enhanced high-yield tools is to allow you to click only two buttons and create a class. Of course, if this is what I want. The classes created by vs.net for us are as follows:
Public Class Class2
{
PublicClass2 ()
{
//
//Todo: Add constructor logic here
//
}
}
This is a public class, which usesProgramSetCodeBlocks are visible. This visibility level is too high, and many independent classes should be internal (internal. You can restrict access by embedding a protected or private class in an existing class. The lower the access level, the less likely it will be to update the entire system in the future. The fewer places you can access the type, and the fewer places you need to modify when updating.
Expose only the content to be exposed. Try to implement public interfaces on the class to reduce the visible content. You can find an example using the enumerator mode in the. NET Framework library. system. arraylist contains a private class, arraylistenumerator, which only implements the ienumerator interface:
// Example, not complete source
Public Class Arraylist: ienumerable
{
Private Class Arraylistenumerator: ienumerator
{
//Contains specific implementation
//Movenext (), reset (), and current.
}
Public Ienumerator getenumerator ()
{
Return NewArraylistenumerator (This);
}
// Other arraylist members.
}
For users like us, we do not need to know the arraylistenumerator class. All you need to know is that when we call the getenumerator function on the arraylist object, what you get is an object that implements the ienumerator interface. The specific implementation is a clear class .. Net Framework designers use the same pattern in another collection class: the hash table (hashtable) contains a private hashtableenumerator, the queue (Queue) contains a queueenumerator, and so on. Private enumeration classes have more advantages. First, the arraylist class can completely replace the type that implements ienumerator, And you have become a wise programmer without damaging any content. In fact, the enumerator class must not be CLS compatible because it is not public (see clause 30 ). Its public interfaces are compatible. You can use the enumerator without having to know any details about the implemented class.
Creating internal classes is a commonly used method to limit the visible range of types. By default, many programmers always create public classes and never consider other methods. This is about vs.net. We should replace the default without thinking. We should carefully consider where your type will be used. Is it visible to all users? Or is it mainly used inside an assembly?
By using interfaces to expose functions, you can create internal classes more easily without limiting their usage outside the Assembly (see clause 19 ). What type should be public? Or is there a better interface aggregation to describe its functions? Internal classes allow you to replace a class with different versions, as long as they implement the same interface. For example, consider the problem of phone number verification:
Public Class Phonevalidator
{
Public Bool Validatenumber (phonenumber pH)
{
//Perform validation
//Check for valid area code, exchange
Return True;
}
}
After a few months, this class can still work well. When you get an international phone number request, the previous phonevalidator fails. It only targets us phone numbers. You still need to verify the US phone number. Now, you need to verify the international phone number during installation. Instead of pasting additional function code into a class, it is better to cut off two different content coupling practices and directly create an interface to verify the phone number:
Public Interface Iphonevalidator
{
BoolValidatenumber (phonenumber pH );
}
Next, modify the existing phone verification, and use the interface to implement it as an internal class:
Internal Class Usphonevalidator: iphonevalidator
{
Public Bool Validatenumber (phonenumber pH)
{
//Perform validation.
//Check for valid area code, exchange.
Return True;
}
}
Finally, you can create a class for international phone number verification:
Internal Class Internationalphonevalidator: iphonevalidator
{
Public Bool Validatenumber (phonenumber pH)
{
//Perform validation.
//Check international code.
//Check specific phone number rules.
Return True;
}
}
To achieve this, you need to create an appropriate class, which is based on the telephone number type class. You can use the factory-like mode to implement this idea. Only interfaces are visible outside the assembly. The actual class is the special class used for different regions in the world, which is visible only within the Assembly. You can create different verification classes for verification in different regions, without worrying about other assemblies in the system.
You can also create a public abstract class for phonevalidator, which contains the implementation of universal verification.Algorithm. Users should be able to access public functions through the base class of the Assembly. In this example, I prefer to use public interfaces, because even with the same functions, this is relatively less. Others may prefer abstract classes. No matter which method is used, as few public classes as possible in the program set.
These exposed public classes and interfaces are your contract: You must keep them. The more chaotic interfaces are exposed, the more you will be restricted in the future. The fewer public types are exposed, the more options are available in the future to expand or modify any implementations.