Home > other >  passing One class as input to another class that takes multiple reference interfaces for his constru
passing One class as input to another class that takes multiple reference interfaces for his constru

Time:06-07

I have Manager class that inherit multiple interfaces and implements them.

class iperson
{
    public:
    virtual void doSomething1() = 0;
}

class imachine
{
    public:
    virtual void doSomething2() = 0;
}

class ibook
{
    public:
    virtual void doSomething3() = 0;
}
class Manager: iperson, imachine, ibook
{
    public:
    void doSomething1() override 
    {/** implemetation **/}
    
    void doSomething2() override
    {/** implemetation **/}
    
    void doSomething3() override
    {/** implemetation **/}

    /*** 
    another code and implemetation 
    ****/
} 

And there is Employee class that takes Manager implementation as input for his constructor

class Employee
{
    Employee(iperson& person, imachine& machine, ibook& book)
    { /*** some code ***/ }
}

And when i need to pass Manger to Employee from Manager class, I end up with code like this

/** That looks bad passing three this XD **/
Employee employee(*this, *this, *this);

Why using interfaces instead of passing Manager reference?(what i'm trying to achieve) 1- to be able to mock these methods while testing the employee class 2- to restrict access of employee classes to just these methods, not all Manager methods

So the question is: is there better solution and is there a way to istead passing the three (*this) just passing one or something?

CodePudding user response:

Yes. (There is a better way).

Consider the way you wrote your inheritance (I don't know if that was intentional):

class IManager: iperson, imachine, ibook

(instead of:

class IManager: public iperson, public imachine, public ibook

If your use of private inheritance is intentional in your example, write your manager as:

class IManager: 
    private iperson, 
    private imachine,
    private ibook
{
    // add these:
    iperson& as_person() { return *this; }
    imachine& as_machine() { return *this; }
    ibook& as_book() { return *this; }
};

This disconnects the fact that your imanager is a person from the requirement to procide a person to client code.

In the future you may want to change it to (for example):

class IManager: 
    private imachine,
    private ibook
{
    // add these:
    virtual iperson& as_person() = 0;
    imachine& as_machine() { return *this; }
    ibook& as_book() { return *this; }
};

class ConcreteManager: public IManager
{
    iperson& as_person() override
    {
        person_facade = PersonForManager(*this);
        return person_facade;
    }

private:
    person_facade * person; // no longer written as inheritance
}

Since you use methods for the different aspects of your interface, you can change them in a single place.

CodePudding user response:

How about

class IManager: iperson, imachine, ibook
{
} 

class Manager :IManager
{

    public:
    void doSomething1() override 
    {/** implemetation **/}
    
    void doSomething2() override
    {/** implemetation **/}
    
    void doSomething3() override
    {/** implemetation **/}

    /*** 
    another code and implemetation 
    ****/
} 

then you can do

class MockManager: IManager
{
    public:
    void doSomething1() override 
    {/** implemetation **/}
    
    void doSomething2() override
    {/** implemetation **/}
    
    void doSomething3() override
    {/** implemetation **/}

    /*** 
    another code and implemetation 
    ****/
} 

and

class Employee
{
    Employee(IManager &man)
    { /*** some code ***/ }
}
  • Related