Combination mode is a "structural" mode. The structure of the structure is two or more, indicating the activity between the object, which is related to the structure of the object.
First, a small example of a combination mode:
As shown in the figure: There are two boxes: Game Box and Internet Box in the system, and the client needs to be invoked by the interfaces of the two classes. In order to simplify the work of the customer, the Xbox class is created, the program code is as follows:
Gamebox code:
Public Class Gamebox
{
Public void PlayGame ()
{
Console.writeline ("Plading Game");
}
}
Internetbox code:
Public Class InternetBox
{
Public void connectionTointernet ()
{
Console.writeline ("Connect to Internet");
}
Public void getmail ()
{
Console.writeline ("Check Email");
}
}
Xbox code:
Public Class Xbox
{
Private gamebox mgamebox = NULL;
Private internetbox minternetbox = null;
Public Xbox ()
{
Mgamebox = new gamebox ();
MINTERNETBOX = New InternetBox ();
}
Public void PlayGame ()
{
mgamebox.playgame ();
}
Public void connectionTointernet ()
{
MinternetBox.ConnectTointernet ();
}
Public void getmail ()
{
MINTERNETBOX.GETMAIL ();
}
}
The way Gamebox and Internetbox encapsulated in Xbox, so that the user faces greatly simplified, the code called is as follows:
Public Class Cscomposite
{
Static void
Main
(String [] ARGS)
{
Xbox x = new xbox ();
Console.writeline ("PlayGame!");
X.PlayGame ();
Console.writeLine ();
Console.WriteLine ("Internet Play Game!");
X.connectTointernet ();
X.PlayGame ();
Console.writeLine ();
Console.writeline ("e-mail!");
x.getmail ();
}
}
It can be seen that users only need to understand the Xbox interface.
Application example of combined mode
The combination mode is suitable for the following cases: two or more classes have similar forms, or commonly representing a complete concept, the outside user also wants them to combine them, you can combine these classes " Get up, becoming a new class, users only need to call this new class.
Let's take an example to illustrate an actual application of the Composite mode. The following Class view:
The Employee class is an implementation of the AbstractEmployee interface. The BOSS class is a subclass of Employee, and EmpNode is inherited from the Treenode class from the tree view. Let's take a look at the code: AbstractEmployee, this is an interface that provides the following methods:
Public interface AbstractEmployee {float getsalary (); // Get current salary string getName (); // get name bool isleaf (); // true if leaf void add (string nm, float salary); // add substerdinate void add ( Abstract "; // get subordinates); // get child float (); // get child float getsalaries (); // Get salaries of all};
The Employee class is an implementation of the AbstractEmploye interface
public class Employee: AbstractEmployee {protected float salary; protected string name; protected ArrayList subordinates; // ------ public Employee (string nm, float salry) {subordinates = new ArrayList (); name = nm; salary = salry ;} // -------------- Public Bool ISLAF () {Return Name;} // ------ Public Bool Isleaf ) {Return subordinates.count == 0;} // ------ Public Virtual Void Add (String NM, Float Salry) {Throw new Exception ("No Subordinates In Base Employee Class");} // ---- public virtual void add (AbstractEmployee emp) {throw new Exception ( "No subordinates in base employee class");} // ------ public IEnumerator getSubordinates () {return subordinates.GetEnumerator ();} Public Virtual Abstract () {Return Null;} // ------ public float getSalaries () {float sum; AbstractEmployee esub; // get the salaries of the boss and subordinates sum = getSalary (); IEnumerator enumSub = subordinates.GetEnumerator (); while (enumSub.MoveNext ()) {ESUB = (AbstractractemPloyee) Enumsub.current; Sum = esub.getsalaries ();} return sum;}} From the Employee interface and one of his implementations, the following is likely to combine this type of data into The structure of a tree.
The BOSS class is a derived of the Employee class, he has heavy loaded the Add and getChild methods of the Employee class:
Public Class Boss: Employee {Public Boss (String Name, Float Salry): Base (Name, Salary) {} // ------ Public Boss (AbstractEmployee EMP): Base (Emp.GetName (), Emp.getsalary ()) {} // ------ Public Override Void Add (String nm, float salary) {AbstractEmployeE EMP = New Employee (nm, salary); Subordinates.Add (EMP);} // ---- - public override void add (AbstractEmployee emp) {subordinates.Add (emp);} // ------ public override AbstractEmployee getChild () {bool found; AbstractEmployee tEmp = null; IEnumerator esub; if (getName () .Equals (GetName ())) Return this; Else {FOUND = false; eSub = Subordinates.GeteNumerator (); while (! Found && eSub.movenext ()) {temp = (Abstract;) eSub.current; found = (Temp .getname (). Equals (name)); if (! found) {if (! Temp.is Leaf ()) {TEMP = Temp.getChild (); FOUND = (Temp.getName (). Equals (name));}}}}}}}} Return Temp; Else Return New Employee ("New Person", 0) }}} GetChild method is a recursive call. If Child is not Leaf, continue to call. The above class expressed a structure of a tree, indicating the level of leadership and employees in the company.
Now let's take a look at the goal that this program needs to be reached, and the program is running the following interface:
There is a tree map on the interface, showing a company's organizational structure, click on these employees, will appear in the following. There are two trees in the program: one is the actual tree on the picture, and the other is the virtual tree of employees in the company. The tree node on the screen is Treenode type, and the employee's virtual tree node is the AbstractEmployee type. We can use a combination mode to create a new "node", combined the characteristics of these two nodes, simplifying the form of forms that need to be handled, please see the following code: public class Empnode: Treenode {private AbstractEmployee Emp; Public EmpNode (ABSTRACTEMPLOYEE AEMP): Base (AEMP.GETNAME ()) {EMP = AEMP;} // ----- Public Abstract "} {return EMP;}}
The EmpNode class is a subclass of the Treenode class. He has all the features of the Treenode class, and he also combines the characteristics of the AbstractEmployee type. This has been simplified in this way. Below is the code snippet of the Form class, I omit some of the automatically generated code:
public class Form1: System.Windows.Forms.Form {private System.Windows.Forms.Label lbSalary; ///
}} // ----- private void buildtree () {EmpNode Nod; NOD = New EmpNode (prez); rootnode = nod; Emptree.Nodes.Add (NOD); addNodes (NOD, prez);} // ----- Private void getNodesum (EmpNode Node) {Abstract Sum; EMP = Node.GETEMPLOYEE (); Sum = Emp.Getsalaries (); lbsalary.text = Sum.tostring ();} // ---- private void addNodes (EmpNode nod, AbstractEmployee emp) {AbstractEmployee newEmp; EmpNode newNode; IEnumerator empEnum; empEnum = emp.getSubordinates (); while (empEnum.MoveNext ()) {newEmp = (AbstractEmployee) empEnum.Current; NewNode = New Empnode (newemp); Nod.Nodes.Add (newNode); addNodes (newnode, newemp);}} // ------ private float rand_sal (float sal) {float rnum = rand.next () RNUM = rnum / int32.maxvalue; return rn UM * SAL / 5 SAL; constructor code after InitializeComponent call //} ///
/ Summary> [STAThread] static void Main () {Application.Run (new Form1 ());} private void EmpTree_AfterSelect (object sender, TreeViewEventArgs e) {EmpNode node; node = (EmpNode) EmpTree.SelectedNode; getNodeSum (node) }}} The EMPTREE_AFTERSELECT method is the tree diagram to click on the response method of the node event. When the user clicks the node, the corresponding salary is displayed in the text bar. The combination mode has been described, and there is no relationship between the following things and the combination mode.
Why use Interface
Why do I create an employee's Interface in the program? We can create a Class Employee, and then generate BOSS, you can implement the above features.
Using Interface is to isolate the display program on the screen from the background service data program. The screen display program only needs to care about "employees" which interfaces can be worked, not to ask for specific details, such as salary computational rules. If you need to perform unit testing of interface classes and data classes, this approach (that is, this program is tested). At the test picture, you can implement some false employees on the employee interface, where the methods and properties are assumed to test, so that the display can be tested is correct. Generally speaking, if you want to perform unit testing, you should consider "turability" from the program from the design phase, where important is to depart the interface to the business logic.
Regarding how to improve the testability of the program, I will have some experience in the future.