The common code design patterns in management software come from business needs and inappropriate places to welcome criticism.
1 re-try Retry mode
Scenario: When connecting to a database server, if the SQL Server database is not started or is starting, we need to have a connection retry policy. When sending an e-mail notification, we also need to try to send the message to the destination user after sending failed.
Code reference:
int maxretry = 30;
int retryInterval = 10000;
for (int i = 1; I <= maxretry; i++)
{
Try
{
Connect to the database server
}
catch (Exceptions exception)
{
if (I < maxretry)
Thread.Sleep (RetryInterval);
Return Returns or stops the retry operation
}
}
This pattern is primarily a retry behavior until the execution is completed or the time or number of times that the contract is exceeded is discarded.
2 before-perform-after Check-execute-transfer mode
Scenario: Before doing a business operation, a subclass must perform a condition or environment check to override the base class's behavior before performing the corresponding business operation, and then continue to transfer the results of this operation to other business units.
To print the report as an example, the business form needs to check whether the currently logged on user has print permissions, or cancel the operation if no permissions are available. code example:
protected internal virtual bool Doperformprint ()
{
Cancelablerecordprinteventargs e = new Cancelablerecordprinteventargs (this. Currententity, Selectionforumlas, Formulafields, parameterfields);
This. Onbeforeprint (e);
if (this._beforeprint! = null)
This._beforeprint (this, e);
if (E.cancel)
return false;
This. Print (ref Selectionforumlas, ref formulafields, ref parameterfields);
EventArgs args = new EventArgs ();
This. Onafterprint (args);
if (this._afterprint! = null)
This._afterprint (this, args);
}
This code should be easy to understand I say this design pattern, the first paragraph is conditional check, if we pass in the subclass of parameter E. Cancel=true, then
This method returns and no longer executes the print method. This design pattern is used more in the event mechanism. The base class can be referenced in order to control the overall behavior of the business unit without losing flexibility.
3 Try Mode
Scenario: Try to execute a business unit and determine the next behavior with its results.
For example, if we load the data, if the load fails, then the next step is to block the data binding, such as transferring the file, if the two parties fail, then you want to block the file transfer.
code example:
private void LoadData ()
{
Try
{
Findandloaddata ()
This._isdataloaded = true;
}
catch (Exception Exception)
{
This._isdataloaded =false;
}
}
The key to this pattern is the variable _isdataloaded defined. In this method, we try to load the data and, if there is an exception, set this variable to false to indicate that the load failed, and the other business unit checks the value of the variable to determine what to do next.
This behavior is also harmful, it hides the real cause of the anomaly, often used in some interface operations, frequently throw a variety of exceptions will be offensive to users, then you can refer to this mode, after attempting to fail, based on the status value to prevent further errors.
4 BackgroundWorker Multi-threaded work
Scenario: Time-consuming business operations such as business computing or reading data, such as demand calculation, work order batch kits, planned order origination, etc., can be used to improve efficiency.
Application code Example:
List<loadmasterscheduleworker> workers = new list<loadmasterscheduleworker> ();
for (int i = 0; i < max_running_thread; i++)
{
Loadmasterscheduleworker worker = new Loadmasterscheduleworker (this, MRP, mpsrows, loadedmpsitems);
Workers. ADD (worker);
}
Workerthreadbase.startandwaitall (workers. ToArray ());
Max_running_thread usually takes the number of CPUs in the current system (Max_running_thread), and in the actual working thread, performs the data assignment and initiates the corresponding business operation in the following way:
while (_mpsrows.count > 0)
{
DataRow mpsrow = null;
if (!_mpsrows.trytake (out Mpsrow))
Break
Loadmasterschedule (_MRP, Mpsrow);
}
The TryTake data row (DataRow) is kept from the Dictionary<datarow> collection until all the data is taken out.
Be aware of the last sentence of the previous method Startandwaitall method, here to wait for all the current child threads to complete, to avoid the data after the operation of the subsequent business operations.
Workerthreadbase The source code reference here.
Http://stackoverflow.com/questions/597590/c-sharp-threading-patterns-is-this-a-good-idea
Http://files.cnblogs.com/files/JamesLi2015/WorkerThreadBase.zip
5 Data class
Scenario: Reduce unnecessary character writing errors in your code and improve program maintainability.
The old code is this:
DataTable query = new Fastserializabledatatable ("bomroutingtable");
Query. Columns.Add ("Bomno", typeof (String));
Query. Columns.Add ("Seqno", typeof (decimal));
Query. Columns.Add ("OpCode", typeof (String));
After applying the data class, the code is like this:
DataTable query = new Fastserializabledatatable ("bomroutingtable");
Query. Columns.Add (Bomfields.bomno, typeof (String));
Query. Columns.Add (Bomfields.seqno, typeof (decimal));
Query. Columns.Add (Bomfields.opcode, typeof (String));
Class Bomfields
{
Public Const string Bomno = "Bomno";
Public const string Seqno = "Seqno";
Public Const string OpCode = "OpCode";
}
The new code design approach adds a type definition, adds a bit of complexity, and improves maintainability. The columns that create the DataTable come from a type definition and can significantly improve writing efficiency if there are multiple places where tables are created.
6 History Record
Scenario: The standard BOM in ERP needs to be changed by ECN, if this mode is applied to other business, then other documents, such as purchase order modification or sales order modification, should be recorded before the change.
Example code:
Bomhistoryentity bomhistory = new bomhistoryentity ();
Initialbomhistoryheaderinactivation (Bomhistory, ECN, canupdate);
return bomhistory;
The change record corresponds to the running account and records the value before each business modification. Change records can also be achieved through the data audit function, but the audit function is too abstract, can only be recorded to the table field changes, to achieve two rows of data record field values accurate comparison, but also need to develop interface programs to adapt to specific business documents.
History mode The biggest killer is anti-audit, anti-posting, if the business documents can be repeatedly modified, after the audit returned, anti-audit can be modified, so repeated operations, will produce a lot of historical data.
7 hashing Verify Hash value verification
Scenario: When a file is transferred, after the file transfer is complete, you need to verify that the MD5 value or SHA1 is consistent before and after the file transfer to ensure that the file does not lose bytes.
In some important business scenarios, such as transfer, recharge, system login, and after the completion of business operations we also need to verify whether the business is reasonable.
code example:
Session = Login (UserId, PasswordHash, Companycode, Languagecode, Hostentry.hostname, Domainusername, Currentprocess.sessionid)
Assemblyversion.company, Assemblyversion.product, Assemblyversion.version, Assemblyversion.fileversion, Assemblyversion.product, session. UserId, session. UserGroup, Session.companycode, session. SessionId, session. Languagecode, session. HostName, session. Domainusername}));
String Privatekey = "...";
String Serverhash = rsacryptionhelper.decryptstring (session. Clienthashvalue, Privatekey);
if (String.compareordinal (Clienthash, serverhash)! = 0)
throw new Appexception ("Unable to login, unexpected error detected");
After the first line of code is successfully logged in, the server returns a Session object that contains a Clienthashvalue MD5 value, while we construct the client's login information again into a string for MD5 processing to compare the values of the two. If the inconsistency could be an illegal login request, throw an exception to prevent the login system from logging in.
This method can also be applied to multiple versions of the policy, the system to prevent the 3.2 version of the client login to the 2.1 version of the server side, notice that the above code has the version parameter, will throw an exception. This ensures that a single computer installs multiple versions of the server side without conflicting with each other.
Seven types of programming patterns