|OOP| Learn “Factory Pattern” from Android Telephony

Factory pattern is a basic pattern in grant software framework.
We create object, parent, with common interface to create new type of object.
The common interface is a static member-function (static factory method) which creates & returns instances, hiding the details of children.

The following will show a snappiest code of Android Q.

In the class “PhoneFactory”, the interfaces of telephone starts from here, makeDefaultPhone which creates phones and interfaces.
Then refer to createPhone …

createPhone will create real phone according to their type.
Notice this method, it returns “Phone”.

//https://android.googlesource.com/platform/frameworks/opt/telephony/+/master/src/java/com/android/internal/telephony/PhoneFactory.java

private static Phone createPhone(Context context, int phoneId) {
    int phoneType = TelephonyManager.getPhoneType(RILConstants.PREFERRED_NETWORK_MODE);
    Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " phoneId = " + phoneId);
    // We always use PHONE_TYPE_CDMA_LTE now.
    if (phoneType == PHONE_TYPE_CDMA) phoneType = PHONE_TYPE_CDMA_LTE;
    TelephonyComponentFactory injectedComponentFactory =
    TelephonyComponentFactory.getInstance().inject(GsmCdmaPhone.class.getName());
    return injectedComponentFactory.makePhone(context,
            sCommandsInterfaces[phoneId], sPhoneNotifier, phoneId, phoneType,
            TelephonyComponentFactory.getInstance());
}

Look at “makePhone”, return “GsmCdmaPhone” !!

//https://android.googlesource.com/platform/frameworks/opt/telephony/+/master/src/java/com/android/internal/telephony/TelephonyComponentFactory.java

public Phone makePhone(Context context, CommandsInterface ci, PhoneNotifier notifier,
        int phoneId, int precisePhoneType,
        TelephonyComponentFactory telephonyComponentFactory) {
    return new GsmCdmaPhone(context, ci, notifier, phoneId, precisePhoneType,
            telephonyComponentFactory);
}

References:
https://www.geeksforgeeks.org/design-patterns-set-2-factory-method/
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm


Another example,
https://github.com/zivww/Cpp17-DataStructure-and-Algorithm/blob/master/Interview/ObjectOrientedProgramming/design_pattern_factory.cpp

#include <iostream> 
using namespace std; 
  
enum PhoneType { 
    Gsm,    Cdma,    Ims 
}; 

// Library classes 
class Phone { 
public: 
    virtual void printType() = 0; 
    static Phone* Create(PhoneType type); 
}; 
class GsmPhone : public Phone { 
public: 
    void printType() { 
        cout << "I am GsmPhone" << endl; 
    } 
}; 
class CdmaPhone : public Phone { 
public: 
    void printType() { 
        cout << "I am CdmaPhone" << endl; 
    } 
}; 
class ImsPhone : public Phone { 
    public: 
    void printType() { 
        cout << "I am ImsPhone" << endl; 
    } 
}; 

// !!This is the key!!
// Factory method to create objects of different types. 
// Change is required only in this function to create a new object type 
Phone* Phone::Create(PhoneType type) { 
    if (type == Gsm) 
        return new GsmPhone(); 
    else if (type == Cdma) 
        return new CdmaPhone(); 
    else if (type == Ims) 
        return new ImsPhone(); 
    else return NULL; 
} 


// PhoneProxy class 
class PhoneProxy { 
public: 
    // PhoneProxy doesn't explicitly create objects 
    // but passes type to factory method "Create()" 
    PhoneProxy(PhoneType pType) { 
        PhoneType type = pType; 
        pPhone = Phone::Create(type); 
    } 
    ~PhoneProxy() { 
        if (pPhone) { 
            delete[] pPhone; 
            pPhone = NULL; 
        } 
    } 
    Phone* getPhone()  { 
        return pPhone; 
    } 
  
private: 
    Phone *pPhone; 
}; 

// Driver program 
int main() { 
    PhoneProxy *pPhoneProxy = new PhoneProxy(Ims); 
    Phone * pPhone = pPhoneProxy->getPhone(); 
    pPhone->printType(); //I am ImsPhone
    return 0; 
}