MarvellousWorks recently began to provide backend access services to major customers, allowing them to integrate B2B services with multiple online businesses.
The general process is as follows:
1) The customer sends the request to the "Queue Service Platform" of MarvellousWorks in the form of a message through the message queue ".
2) for the sake of security, the processing logic of the Message Platform actively captures the latest submitted packets from the queue service platform.
3) After capturing a new message, the Message Platform disassembles the message, reads the information, and verifies its validity.
4) The "Message Platform" will disassemble and verify that valid message information is written to the database.
Restrictions:
1) message data is in XML format, and its XML Schema is defined and released by MarvellousWorks in advance, and each customer follows the instructions
2) because the customer uses different Queue products, the "Queue Service Platform" plans to support Microsoft MSMQ and ibm mq. It may also support ORACLE's Advanced Queue and BEA's MessageQ in the future.
3) because different online services of MarvellousWorks are established at different times, the databases include ORACLE, MySQL, and SQL Server.
Now you are the architect to design the "Message Platform" service program.
1. the queue access interface and database access interface are defined as follows:
/// <Summary>
/// Queue access interface
/// </Summary>
Interface IQueue
{
XmlDocument Peek ();
XmlDocument Dequeue ();
}
/// <Summary>
/// Base classes of online business data entities
/// </Summary>
Abstract class EntryBase {}
/// <Summary>
/// To simplify the example, convert all business entities to the DataRow type that comes with ADO. NET before writing them to the database.
/// </Summary>
Interface IEntryDataConverter
{
DataRow ToDataRow (EntryBase entry );
}
/// <Summary>
/// Database access interface
/// </Summary>
Interface IDatabase
{
IEntryDataConverter DataConverter {get; set ;}
Void Write (EntryBase entry );
Void Write (IEnumerable <EntryBase> entries );
}
2. Use the adapter mode described in this chapter to design the "Message Platform" processing interface, and create a simple prototype to verify your ideas through unit testing.
3. Because there are many types of message data, please use the data adaptation mechanism introduced in this chapter to complete a data adaptation prototype with the message processing interface above, and pass the unit test verification.
Tip:
To ensure the stability of the processing logic of the "Message Platform", we recommend that you use the Adapter-Adapter Cascade Method to capture packets and import them to the database.
Reference answer
1. to simplify the example, convert all business entities to the DataRow type that comes with ADO. NET before writing them to the database.
2. Empty data is used for all calling interfaces.
The objective is to verify the structure validity through unit tests.
1. Simulated queue product interfaces and Their adapters
Class Msmq
{
String current;
/// <Summary>
/// Incompatible interface, equivalent to Peek ()
/// </Summary>
Public string Head
{
Get
{
Trace. WriteLine ("Msmq. Head ");
Current = Guid. NewGuid (). ToString ();
Return current;
}
}
/// <Summary>
/// Incompatible interface, equivalent to Dequeue ()
/// </Summary>
/// <Returns> </returns>
Public string GetHead ()
{
Trace. WriteLine ("Msmq. GetHead ()");
Var result = current;
Current = string. Empty;
Return result;
}
}
Class MsmqAdapter: IQueue
{
Msmq queue = new Msmq ();
Public XmlDocument Peek ()
{
Trace. WriteLine ("MsmqAdapter. Peek ()");
Trace. WriteLine (queue. Head );
Return null;
}
Public XmlDocument Dequeue ()
{
Trace. WriteLine ("MsmqAdapter. Dequeue ()");
Trace. WriteLine (queue. GetHead ());
Return null;
}
}
Class IbmMq: Queue <string>
{
String lastest;
Public new string Peek ()
{
Lastest = Guid. NewGuid (). ToString ();
Base. Enqueue (lastest );
Trace. WriteLine ("IbmMq. Peek ()");
Return base. Peek ();
}
Public new string Dequeue ()
{
Trace. WriteLine ("IbmMq. Dequeue ()");
Return base. Dequeue ();
}
}
Class IbmMqAdapter: IQueue
{
IbmMq queue = new IbmMq ();
Public XmlDocument Peek ()
{
Trace. WriteLine ("IbmMqAdapter. Peek ()");
Trace. WriteLine ("Message:" + queue. Peek ());
Return null;
}
Public XmlDocument Dequeue ()
{
Trace. WriteLine ("IbmMqAdapter. Dequeue ()");
Trace. WriteLine ("Message:" + queue. Dequeue ());
Return null;
}
}
2. Simulated database product Interfaces
Class OracleDB
{
Public void WriteData (string [] [] data)
{
Trace. WriteLine ("OracleDb. WriteData (string [] [] data )");
}
}
Class SqlServer
{
Public void ExecuteNonSql (DataSet data)
{
Trace. WriteLine ("SqlServer. ExecuteNonSql (DataSet data )");
}
Public void InsertOneRecord (DataRow data)
{
Trace. WriteLine ("SqlServer. InsertOneRecord (DataRow data )");
}
}
Class MySqlDatabase
{
Public void ExecuteCommand (string SQL)
{
Trace. WriteLine ("MySqlDatabase. ExecuteCommand (string SQL )");
}
}
3. Business Entities of various simulated examples
Class Order: EntryBase {}
Class DeliveryOrder: EntryBase {}
Class WarehouseEntry: EntryBase {}
Class InventoryList: EntryBase {}
4. Simulated Data adaptation interfaces and Entity Data adaptation types for individual business entity types
Interface IMessageConverter
{
IEnumerable <EntryBase> ConvertMessageToQuerable (XmlDocument message );
}
Abstract class DatabaseAdapterBase: IDatabase
{
Public IEntryDataConverter DataConverter {get; set ;}