中介者(Mediator)模式

转自:http://liulinqi206.blog.163.com/blog/static/13460476620120173323449/

一、什么是中介者模式
    Mediator模式也叫中介者模式,是由GoF提出的23种软件设计模式的一种。Mediator模式是行为模式之一,在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用

 

在Mediator模式中,每一个Colleague维护一个Mediator,交互的时候可以通过ConcreteMediator的子函数进行处理。 
    两个交互的对象并不知道其交互的方向,而且他们也不是显示的处理交互过程,一切都交给Mediator对象进行完成。
    该模式将所有的通信封装在一个类中间,将通信转换为一对多的通信,通过这种封装,对象不必各自维护通信协议,便于集中管理。

[转载]C++设计模式18:Mediator模式


class Mediator;
class Colleage
{
public:
 virtual ~Colleage(){};
 virtual void Action()=0;
 virtual void SetState(const string& sd)=0;
 virtual string GetState()=0;
protected:
 Colleage(){};
 Colleage(Mediator* mdt){this->m_mdt=mdt;};
 Mediator* m_mdt;
}; 
 
 
class ConcreteColleageA:public Colleage
{
public:
 ConcreteColleageA(){};
 ConcreteColleageA(Mediator* mdt):Colleage(mdt){}
 ~ConcreteColleageA(){};
 void SetState(const string& sd){m_sd=sd;}
 string GetState(){return m_sd;}
 void Action();
private:
 string m_sd;
};
 
 
class ConcreteColleageB:public Colleage
{
public:
 ConcreteColleageB(){};
 ConcreteColleageB(Mediator* mdt):Colleage(mdt){}
 ~ConcreteColleageB(){};
 void SetState(const string& sd){m_sd=sd;};
 string GetState(){return m_sd;}
 void Action();
private:
 string m_sd;
};
 
 
class Mediator
{
public:
 virtual ~Mediator(){};
 virtual void DoActionFromAtoB()=0;
 virtual void DoActionFromBtoA()=0;
protected:
 Mediator(){};
};
 
 
class ConcreteMediator:public Mediator
{
public:
 ConcreteMediator(){};
 ConcreteMediator(Colleage* ClA,Colleage* ClB){m_ClA=ClA;m_ClB=ClB;};
 ~ConcreteMediator(){};
 void SetConA(Colleage* ClA){m_ClA=ClA;}
 void SetConB(Colleage* ClB){m_ClB=ClB;}
 Colleage* GetConA(){return m_ClA;}
 Colleage* GetConB(){return m_ClB;}
 void DoActionFromAtoB(){m_ClB->SetState(m_ClA->GetState());}
 void DoActionFromBtoA(){m_ClA->SetState(m_ClB->GetState());}
 void IntroColleage(Colleage* ClA,Colleage* ClB)
 {
  m_ClA=ClA;m_ClB=ClB;
 }
private:
 Colleage* m_ClA;
 Colleage* m_ClB; 
};
 
 
void ConcreteColleageA::Action()
{
 m_mdt->DoActionFromAtoB();
 cout<<"CONB "<<this->GetState()<<endl;
}
void ConcreteColleageB::Action()
{
 m_mdt->DoActionFromBtoA();
 cout<<"CONA "<<this->GetState()<<endl;
}
 
 
void main()
{
 ConcreteMediator* m=new ConcreteMediator();
 ConcreteColleageA* c1=new ConcreteColleageA(m);
 ConcreteColleageB* c2=new ConcreteColleageB(m);
 m->IntroColleage(c1,c2);
 c1->SetState("jackill");
 c1->Action();
 c2->SetState("rukawa");
 c2->Action();
 cout<<endl;
 c1->SetState("new");
 c1->Action();
 c2->Action();
 cout<<endl;
}

 

 

20. C++实现Behavioral - Mediator模式  

2010-02-05 00:17:07|  分类: Pattern |  标签: |字号大中小 订阅


 

 “Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction” – GoF

用一个中介对象来封装一系列的对象交互。Mediator使各对象不需要显示的相互引用,从而使其耦合松散,以便可以独立地改变他们之间的交互。

 

Object-oriented design encourages the distribution of behavior among objects. Such distribution can result in an object structure with many connections between objects; in the worst case, every object ends up knowing about every other.

 

Though partitioning a system into many objects generally enhances reusability, proliferating interconnections tend to reduce it again. Lots of interconnections make it less likely that an object can work without the support of others—the system acts as though it were monolithic. Moreover, it can be difficult to change the system's behavior in any significant way, since behavior is distributed among many objects. As a result, you may be forced to define many subclasses to customize the system's behavior.

 

在软件构建过程中,经常会出现多个对象相互关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可以使用一个“中介对象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合的引用关系,从而更好地驾驭变化。

 

依赖关系的转化示例:

20. C++实现Behavioral - Mediator模式 - 玄机逸士 - 玄机逸士博客

1.       5个类相互之间两两相互依赖;                                       1.      5各类彼此之间没有直接的依赖关系;

2.       共有10个关系需要维护;                                                2.      共有5个关系需要维护;

3.       如果任意其中一个类发生了改                                         3.     如果任意其中一个类发生了改变,那么

变,那么另外4个类,度需要                                                   只需要修改Mediator即可,其它4个

随之改变;                                                                                  类可以维持不变;

4.    如果要增加一个新类F,那么需要                                    4.    如果要增加一个类F,那么要维护的关系

       维护的关系数量将变为15,并且                                              数量将变为6,原有的5个类不需要做任

    原有的5个类均需要做相应改变。                                            和改变,仅需改变Mediator即可。

 

Applicability:

-          A set of objects communicate in well-defined but complex ways. The resulting interdependencies are unstructed and difficult to understand.

-          Resuing an object is difficult because it refers to and communicates with many other objects.

-          A behavior that’s distributed between several classes should be customizable without a lot of subclassing.

 

Participants:

-          Mediator:

Defines an interface for communicating with Colleague objects.

-          ConcreteMediator:

Implements cooperative behavior by coordinatiing Colleague objects.

Knows and maintains its colleagues.

-          Colleagues

Each Colleague class knows its Mediator object.

Each colleague communicates with its mediator whenever it would have otherwise communicated with another colleague.

        

业务示例:假定有如下图所示的界面:

20. C++实现Behavioral - Mediator模式 - 玄机逸士 - 玄机逸士博客

RadioButtons包含了4个单选,CheckBoxes包含了4个复选框,ComboBox中有4个选项。先假定:

如果RadioButtons中选择了Roption1,那么CheckBoxes中的Coption1就会被选中,ComboBox中的ComOption1就会被选中;如果CheckBoxes中的COption1被选中,那么RadioButtons中的ROption1和ComboBox中的ComOption1就会被选中;如果ComboBox中的ComOption1被选中,那么RadioButtons中的ROption1和CheckBoxes中的Coption1就会被选中。以此类推。另外在这里,RadioButtons和其中的单选按钮被看成是一个对象,4个单选按钮可视为RadioButtons的4个状态;CheckBoxes和ComboBox也是如此。

 

还有一个假设:

CheckBoxes和ComboBox分别只能选择其中一项(即“复选框”也不能“复选”,与其实际功能不符,纯为研究用)

 

优点:

-          将多对多的关系转化为一对多的关系,使对象之间的关系更易于维护;

-          将对象的行为和协作抽象化。

 

缺点:

-          虽然降低了同事类的复杂性,但增加了调停者对象的复杂性;

-          同事类的复用性是以调停者类的不可复用为代价的。

 

C++实现代码:

// Mediator.h

#include <string>

#include <iostream>

 

using namespace std;

 

// 前置声明

class AbstractColleague;

 

// 抽象调停类

class AbstractMediator

{

public:

         // 通知"同事"类,其参数aac为引发事件的对象

         virtual void notify_colleagues(AbstractColleague *aac) = 0;

 

public:

         virtual ~AbstractMediator()

         {

                   cout << "in the destructor of AbstractMediator..." << endl;

         }

};

 

// 抽象"同事"类

class AbstractColleague

{

protected:

         AbstractMediator *mediator;

 

public:

         AbstractColleague(AbstractMediator *mediator)

         {

                   this->mediator = mediator;

         }

 

         ~AbstractColleague()

         {

                   cout << "in the destructor of AbstractColleague..." << endl;

         }

 

public:

         virtual void set_item_true(int i) = 0;

         virtual int get_true_item() = 0;

 

         void on_change(AbstractColleague *aac)

         {

                   mediator->notify_colleagues(aac);

         }

};

 

// 单选按钮

class RadioButtons : public AbstractColleague

{

private:

         bool rButton1;

         bool rButton2;

         bool rButton3;

         bool rButton4;

 

public:

         RadioButtons(AbstractMediator *mediator) : AbstractColleague(mediator)

         {

                   rButton1 = false;

                   rButton2 = false;

                   rButton3 = false;

                   rButton4 = false;

         }

 

         ~RadioButtons()

         {

                   cout << "in the destructor of RadioButtons..." << endl;

         }

 

public:

         void set_item_true(int i)

         {

                   rButton1 = false;

                   rButton2 = false;

                   rButton3 = false;

                   rButton4 = false;

 

                   switch(i)

                   {

                  case 1:

                            rButton1 = true;

                            break;

                   case 2:

                            rButton2 = true;

                            break;

                   case 3:

                            rButton3 = true;

                            break;

                   case 4:

                            rButton4 = true;

                            break;

                   default:

                            rButton1 = true;

                   }

         }

 

         int get_true_item()

         {

                   if(rButton1) return 1;

                   if(rButton2) return 2;

                   if(rButton3) return 3;

                   if(rButton4) return 4;

                   return 1;

         }

 

         void onRadioButtonClick()

         {

                   on_change(this);

         }

};

 

// 复选框

class CheckBoxes : public AbstractColleague

{

private:

         bool cBox1;

         bool cBox2;

         bool cBox3;

         bool cBox4;

 

public:

         CheckBoxes(AbstractMediator *mediator) : AbstractColleague(mediator)

         {

                   cBox1 = false;

                   cBox2 = false;

                   cBox3 = false;

                   cBox4 = false;

         }

 

         ~CheckBoxes()

         {

                   cout << "in the destructor of CheckBoxes..." << endl;

         }

 

public:

         void set_item_true(int i)

         {

                   cBox1 = false;

                   cBox2 = false;

                   cBox3 = false;

                   cBox4 = false;

 

                   switch(i)

                   {

                   case 1:

                            cBox1 = true;

                            break;

                   case 2:

                            cBox2 = true;

                            break;

                   case 3:

                            cBox3 = true;

                            break;

                   case 4:

                            cBox4 = true;

                            break;

                   default:

                            cBox1 = true;

                   }

         }

 

         int get_true_item()

         {

                   if(cBox1) return 1;

                   if(cBox2) return 2;

                   if(cBox3) return 3;

                   if(cBox4) return 4;

                   return 1;

         }

 

         void onCheckBoxClick()

         {

                   on_change(this);

         }

};

 

// 下拉框

class ComboBox : public AbstractColleague

{

private:

         bool cOpt1;

         bool cOpt2;

         bool cOpt3;

         bool cOpt4;

 

public:

         ComboBox(AbstractMediator *mediator) : AbstractColleague(mediator)

         {

                   cOpt1 = false;

                   cOpt2 = false;

                   cOpt3 = false;

                   cOpt4 = false;

         }

 

         ~ComboBox()

         {

                   cout << "in the destructor of ComboxBox..." << endl;

         }

 

public:

         void set_item_true(int i)

         {

                   cOpt1 = false;

                   cOpt2 = false;

                   cOpt3 = false;

                   cOpt4 = false;

 

                   switch(i)

                   {

                   case 1:

                            cOpt1 = true;

                            break;

                   case 2:

                            cOpt2 = true;

                            break;

                   case 3:

                            cOpt3 = true;

                            break;

                   case 4:

                            cOpt4 = true;

                            break;

                   default:

                            cOpt1 = true;

                   }

         }

 

         int get_true_item()

         {

                   if(cOpt1) return 1;

                   if(cOpt2) return 2;

                   if(cOpt3) return 3;

                   if(cOpt4) return 4;

                   return 1;

         }

 

         void onComboBoxClick()

         {

                   on_change(this);

         }

};

 

// 具体调停类

class ConcreteMediator : public AbstractMediator

{

private:

         RadioButtons* rbt;

         CheckBoxes* cbx;

         ComboBox* cbo;

 

public:

         ~ConcreteMediator()

         {

                   cout << "in the destructor of ConcreteMediator..." << endl;

         }

 

         void set_colleagues(RadioButtons* rbt, CheckBoxes* cbx, ComboBox* cbo)

         {

                   this->rbt = rbt;

                   this->cbx = cbx;

                   this->cbo = cbo;

         }

 

         void notify_colleagues(AbstractColleague *aac)

         {

                   int i = aac->get_true_item();

                   rbt->set_item_true(i);

                   cbx->set_item_true(i);

                   cbo->set_item_true(i);

         }

};

 

// Mediator.cpp

#include "Mediator.h"

 

int main(int argc, char **argv)

{

         AbstractMediator* mediator = new ConcreteMediator();

         RadioButtons* rbt = new RadioButtons(mediator);

         CheckBoxes* cbx = new CheckBoxes(mediator);

         ComboBox* cbo = new ComboBox(mediator);

 

         dynamic_cast<ConcreteMediator*>(mediator)->set_colleagues(rbt, cbx, cbo);

        

         // 下面两行模拟RadioButtons的onClick事件触发,并选中第个单选按钮

         rbt->set_item_true(1);

         rbt->onRadioButtonClick();

 

         cout << "Event triggered by the No.1 item of RadioButtons" << endl;

         cout << "rButton" << rbt->get_true_item() << " \tis selected!" << endl;

         cout << "cBox" << cbx->get_true_item() << " \t\tis selected accordingly!" << endl;

         cout << "cOpt" << cbo->get_true_item() << " \t\tis selected accordingly!" << endl;

 

         cout << "------------------------------------------------------" << endl;

 

         // 下面两行模拟CheckBoxes的onClick事件触发,并选中第个复选框

         cbx->set_item_true(2);

         cbx->onCheckBoxClick();

 

         cout << "Event triggered by the No.2 item of CheckBoxes" << endl;

         cout << "rButton" << rbt->get_true_item() << " \tis selected accordingly!" << endl;

         cout << "cBox" << cbx->get_true_item() << " \t\tis selected!" << endl;

         cout << "cOpt" << cbo->get_true_item() << " \t\tis selected accordingly!" << endl;

 

         cout << "------------------------------------------------------" << endl;

 

         // 下面两行模拟ComboBox的onClick事件触发,并选中第个选项

         cbo->set_item_true(3);

         cbo->onComboBoxClick();

 

         cout << "Event triggered by the No.3 item of ComboBox" << endl;

         cout << "rButton" << rbt->get_true_item() << " \tis selected accordingly!" << endl;

         cout << "cBox" << cbx->get_true_item() << " \t\tis selected accordingly!" << endl;

         cout << "cOpt" << cbo->get_true_item() << " \t\tis selected!" << endl;

 

         cout << "------------------------------------------------------" << endl;

 

         delete mediator;

         delete rbt;

         delete cbx;

         delete cbo;

 

         return 0;

}

 

运行结果:

Event triggered by the No.1 item of RadioButtons

rButton1          is selected!

cBox1                is selected accordingly!

cOpt1                is selected accordingly!

------------------------------------------------------

Event triggered by the No.2 item of CheckBoxes

rButton2          is selected accordingly!

cBox2                is selected!

cOpt2                is selected accordingly!

------------------------------------------------------

Event triggered by the No.3 item of ComboBox

rButton3          is selected accordingly!

cBox3                is selected accordingly!

cOpt3                is selected!

------------------------------------------------------

in the destructor of ConcreteMediator...

in the destructor of AbstractMediator...

in the destructor of RadioButtons...

in the destructor of AbstractColleague...

in the destructor of CheckBoxes...

in the destructor of AbstractColleague...

in the destructor of ComboxBox...

in the destructor of AbstractColleague...

 

上述程序的UML类图:

20. C++实现Behavioral - Mediator模式 - 玄机逸士 - 玄机逸士博客 


 

 

三、中介者模式的角色和职责
mediator
    中介者类的抽象父类。
concreteMediator
    具体的中介者类。
colleague关联类的抽象父类。
concreteColleague
    具体的关联类。
四、中介者模式的优点
1. 将系统按功能分割成更小的对象,符合类的最小设计原则
2. 对关联对象的集中控制
3. 减小类的耦合程度,明确类之间的相互关系:当类之间的关系过于复杂时,其中任何一个类的修改都会影响到其他类,不符合类的设计的开闭原则 ,而Mediator模式将原来相互依存的多对多的类之间的关系简化为Mediator控制类与其他关联类的一对多的关系,当其中一个类修改时,可以对其他关联类不产生影响(即使有修改,也集中在Mediator控制类)。
4. 有利于提高类的重用性

 

描述经过Facade模式的改装后,一个子系统的使用端与子系统的关系。图中的大方框代表一个子系统。

    就如同医院的接待员一样,Facade模式的门面类型将使用端与子系统的内部复杂性分隔开,使得使用端只需要与门面对象打交道,而不需要与子系统内部的很多对象打交道。

    Mediator架构模式

    Mediator模式包装了一系列对象相互作用的方式,使得这些对象不必互相明显参照;从而使它们可以较松散地耦合。当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其它的一些对象之间的相互作用;从而可以保证这些相互作用可以彼此独立地变化。

    在下面的示意图中有大量的对象,这些对象既会影响别的对象,又会被别的对象所影响,因此常常叫做同事(Colleague)对象。这些同事对象通过彼此的相互作用形成系统的行为。从图中可以看出,几乎每一个对象都需要与其它的对象发生相互作用,而这种相互作用表现为一个对象与另一个对象的直接耦合。

    此主题相关图片如下:

图5、这是一个过度耦合的系统

    通过引入调停者对象(Mediator),可以将系统的网状结构变成以中介者为中心的星形结构,如下图所示。在这个星形结构中,同事对象不再通过直接的联系与另一个对象发生相互作用;相反地,它通过调停者对象与另一个对象发生相互作用。调停者对象的存在保证了对象结构上的稳定,也就是说,系统的结构不会因为新对象的引入造成大量的修改工作。 
    此主题相关图片如下:

图6、这是一个使用了Mediator架构模式之后的结构图

    比较传统的设计方法,面向对象的技术可以更好地协助设计师管理更为复杂的系统。一个好的面向对象的设计可以使对象之间增加协作性(Collaboration),减少耦合度(Coupling)。一个深思熟虑的设计会把一个系统分解为一群相互协作的同事对象,然后给每一个同事对象以独特的责任,恰当的配置它们之间的协作关系,使它们可以在一起工作。

    在Mediator模式中,所有的成员对象都可以协调工作,但是又不直接相互管理。这些对象都与一个处于中心地位的调停者对象发生紧密的关系,由这个调停者对象进行协调工作。这个协调者对象叫做调停者(Mediator),而调停者所协调的成员对象称做同事(Colleague)对象。

    在Colleague对象内部发生的事件会影响到所有的同事,但是这种影响不是以直接管理的方式直接传到其它的对象上的。记住在小组的成员增加时,这样的相互作用关系是以比指数更快的方式增加的。相反,这种影响仅仅直接影响到调停者对象,而调停者对象反过来会协调其它的同事,形成整个系统的行为。

    如果小组的成员增加时,调停者对象可能会面临修改,而其它的同事则可以装做不知道这个新的成员一样,不必修改。反过来,如果小组的成员之一被从系统中删除的话,调停者对象需要对此做出修改,而小组中其它的同事则不必改动。

 

 

 

 


未运用中介模式前的实现:
Person.java

 
package com.ibeifeng.ex1; 
 
public abstract class Person { 
    private String name; 
    private int condition; 
 
    public Person(String name, int condition) { 
        this.name = name; 
        this.condition = condition; 
    } 
 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
    public int getCondition() { 
        return condition; 
    } 
 
    public void setCondition(int condition) { 
        this.condition = condition; 
    } 
 
    public abstract void getPartner(Person person); 
 
}

Man.java

 
package com.ibeifeng.ex1; 
 
public class Man extends Person { 
 
    public Man(String name, int condition) { 
        super(name, condition); 
    } 
 
    public void getPartner(Person person) { 
        if(person instanceof Man) { 
            System.out.println("汗,我不是同性恋!"); 
        } else { 
            if(this.getCondition() == person.getCondition()) { 
                System.out.println(this.getName() + "和" + person.getName() + "绝配"); 
            } else { 
                System.out.println(this.getName() + "和" + person.getName() + "不相配"); 
            } 
        } 
    } 
 
}

Woman.java

package com.ibeifeng.ex1; 
 
public class Woman extends Person { 
 
    public Woman(String name, int condition) { 
        super(name, condition); 
    } 
 
    public void getPartner(Person person) { 
        if(person instanceof Woman) { 
            System.out.println("汗,我不是同性恋!"); 
        } else { 
            if(this.getCondition() == person.getCondition()) { 
                System.out.println(this.getName() + "和" + person.getName() + "绝配"); 
            } else { 
                System.out.println(this.getName() + "和" + person.getName() + "不相配"); 
            } 
        } 
    } 
 
}

MainClass.java

package com.ibeifeng.ex1; 
 
public class MainClass { 
    public static void main(String[] args) { 
        Person zhangsan = new Man("张三",5); 
        Person lisi = new Man("李四",6); 
 
        Person xiaofang = new Woman("小芳", 6); 
 
        zhangsan.getPartner(xiaofang); 
        lisi.getPartner(xiaofang); 
        zhangsan.getPartner(lisi); 
 
    } 
}

运用了中介模式的代码:
Person.java

package com.ibeifeng.ex2; 
 
public abstract class Person { 
    private String name; 
    private int condition; 
    private Mediator mediator; 
 
 
    public Person(String name, int condition, Mediator mediator) { 
        super(); 
        this.name = name; 
        this.condition = condition; 
        this.mediator = mediator; 
    } 
 
    public Mediator getMediator() { 
        return mediator; 
    } 
 
    public void setMediator(Mediator mediator) { 
        this.mediator = mediator; 
    } 
 
    public String getName() { 
        return name; 
    } 
    public void setName(String name) { 
        this.name = name; 
    } 
    public int getCondition() { 
        return condition; 
    } 
 
    public void setCondition(int condition) { 
        this.condition = condition; 
    } 
 
    public abstract void getPartner(Person person); 
 
}

Man.java

package com.ibeifeng.ex2; 
 
public class Man extends Person { 
 
    public Man(String name, int condition,Mediator mediator) { 
        super(name, condition, mediator); 
    } 
 
    public void getPartner(Person person) { 
        this.getMediator().setMan(this); 
        this.getMediator().getPartner(person); 
    } 
}

Woman.java

package com.ibeifeng.ex2; 
 
public class Woman extends Person { 
 
    public Woman(String name, int condition,Mediator mediator) { 
        super(name, condition, mediator); 
    } 
 
    public void getPartner(Person person) { 
        this.getMediator().setWoman(this); 
        this.getMediator().getPartner(person); 
    } 
 
}

Mediator.java

package com.ibeifeng.ex2; 
 
public class Mediator { 
    private Man man; 
    private Woman woman; 
 
    public void setMan(Man man) { 
        this.man = man; 
    } 
    public void setWoman(Woman woman) { 
        this.woman = woman; 
    } 
 
    public void getPartner(Person person) { 
        //将搭档设置上 
        if(person instanceof Man) { 
            this.setMan((Man)person); 
        } else { 
            this.setWoman((Woman)person); 
        } 
        //判断条件 
        if(man == null || woman == null) { 
            System.out.println("汗,我不是同性恋!"); 
        } else { 
 
            if(man.getCondition() == woman.getCondition()) { 
                System.out.println(man.getName() + "和" + woman.getName() + "绝配"); 
            } else { 
                System.out.println(man.getName() + "和" + woman.getName() + "不相配"); 
            } 
        } 
    } 
 
}


MainClass.java

package com.ibeifeng.ex2; 
public class MainClass { 
    public static void main(String[] args) { 
        Mediator mediator = new Mediator(); 
        Person zhangsan = new Man("张三",7,mediator); 
        Person lisi = new Man("李四",7,mediator); 
        Person xiaofang = new Woman("小芳",7,mediator); 
 
        zhangsan.getPartner(lisi); 
 
        xiaofang.getPartner(lisi); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值