diff --git a/libpldmresponder/platform.hpp b/libpldmresponder/platform.hpp
index ec168f4..be48950 100644
--- a/libpldmresponder/platform.hpp
+++ b/libpldmresponder/platform.hpp
@@ -2,6 +2,7 @@
 
 #include "config.h"
 
+#include "handler.hpp"
 #include "libpldmresponder/pdr.hpp"
 #include "libpldmresponder/utils.hpp"
 
@@ -14,254 +15,269 @@
 
 namespace pldm
 {
-
-using Response = std::vector<uint8_t>;
-
 namespace responder
 {
-
 namespace platform
 {
 
-/** @brief Register handlers for commands from the platform spec
- */
-void registerHandlers();
-
-} // namespace platform
-
-/** @brief Handler for GetPDR
- *
- *  @param[in] request - Request message payload
- *  @param[in] payloadLength - Request payload length
- *  @param[out] Response - Response message written here
- */
-Response getPDR(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Handler for setStateEffecterStates
- *
- *  @param[in] request - Request message
- *  @param[in] payloadLength - Request payload length
- *  @return Response - PLDM Response message
- */
-Response setStateEffecterStates(const pldm_msg* request, size_t payloadLength);
-
-/** @brief Function to set the effecter requested by pldm requester
- *  @param[in] dBusIntf - The interface object
- *  @param[in] effecterId - Effecter ID sent by the requester to act on
- *  @param[in] stateField - The state field data for each of the states, equal
- *        to composite effecter count in number
- *  @return - Success or failure in setting the states. Returns failure in terms
- *        of PLDM completion codes if atleast one state fails to be set
- */
-template <class DBusInterface>
-int setStateEffecterStatesHandler(
-    const DBusInterface& dBusIntf, effecter::Id effecterId,
-    const std::vector<set_effecter_state_field>& stateField)
+class Handler : public CmdHandler
 {
-    using namespace std::string_literals;
-    using DBusProperty = std::variant<std::string, bool>;
-    using StateSetId = uint16_t;
-    using StateSetNum = uint8_t;
-    using PropertyMap =
-        std::map<StateSetId, std::map<StateSetNum, DBusProperty>>;
-    static const PropertyMap stateNumToDbusProp = {
-        {PLDM_BOOT_PROGRESS_STATE,
-         {{PLDM_BOOT_NOT_ACTIVE,
-           "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
-           "Standby"s},
-          {PLDM_BOOT_COMPLETED,
-           "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
-           "BootComplete"s}}},
-        {PLDM_SYSTEM_POWER_STATE,
-         {{PLDM_OFF_SOFT_GRACEFUL,
-           "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
-    using namespace phosphor::logging;
-    using namespace pldm::responder::pdr;
-    using namespace pldm::responder::effecter::dbus_mapping;
-
-    state_effecter_possible_states* states = nullptr;
-    pldm_state_effecter_pdr* pdr = nullptr;
-    uint8_t compEffecterCnt = stateField.size();
-    uint32_t recordHndl{};
-    Repo& pdrRepo = get(PDR_JSONS_DIR);
-    pdr::Entry pdrEntry{};
-
-    while (!pdr)
+  public:
+    Handler()
     {
-        pdrEntry = pdrRepo.at(recordHndl);
-        pldm_pdr_hdr* header = reinterpret_cast<pldm_pdr_hdr*>(pdrEntry.data());
-        if (header->type != PLDM_STATE_EFFECTER_PDR)
-        {
-            recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
-            if (recordHndl)
-            {
-                continue;
-            }
-            return PLDM_PLATFORM_INVALID_EFFECTER_ID;
-        }
-        pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data());
-        recordHndl = pdr->hdr.record_handle;
-        if (pdr->effecter_id == effecterId)
-        {
-            states = reinterpret_cast<state_effecter_possible_states*>(
-                pdr->possible_states);
-            if (compEffecterCnt > pdr->composite_effecter_count)
-            {
-                log<level::ERR>("The requester sent wrong composite effecter "
-                                "count for the effecter",
-                                entry("EFFECTER_ID=%d", effecterId),
-                                entry("COMP_EFF_CNT=%d", compEffecterCnt));
-                return PLDM_ERROR_INVALID_DATA;
-            }
-            break;
-        }
-        recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
-        if (!recordHndl)
-        {
-            return PLDM_PLATFORM_INVALID_EFFECTER_ID;
-        }
-        pdr = nullptr;
+        handlers.emplace(PLDM_GET_PDR,
+                         [this](const pldm_msg* request, size_t payloadLength) {
+                             return this->getPDR(request, payloadLength);
+                         });
+        handlers.emplace(PLDM_SET_STATE_EFFECTER_STATES,
+                         [this](const pldm_msg* request, size_t payloadLength) {
+                             return this->setStateEffecterStates(request,
+                                                                 payloadLength);
+                         });
     }
 
-    std::map<StateSetId, std::function<int(const std::string& objPath,
-                                           const uint8_t currState)>>
-        effecterToDbusEntries = {
-            {PLDM_BOOT_PROGRESS_STATE,
-             [&](const std::string& objPath, const uint8_t currState) {
-                 auto stateSet =
-                     stateNumToDbusProp.find(PLDM_BOOT_PROGRESS_STATE);
-                 if (stateSet == stateNumToDbusProp.end())
-                 {
-                     log<level::ERR>("Couldn't find D-Bus mapping for "
-                                     "PLDM_BOOT_PROGRESS_STATE",
-                                     entry("EFFECTER_ID=%d", effecterId));
-                     return PLDM_ERROR;
-                 }
-                 auto iter = stateSet->second.find(
-                     stateField[currState].effecter_state);
-                 if (iter == stateSet->second.end())
-                 {
-                     log<level::ERR>(
-                         "Invalid state field passed or field not "
-                         "found for PLDM_BOOT_PROGRESS_STATE",
-                         entry("EFFECTER_ID=%d", effecterId),
-                         entry("FIELD=%d",
-                               stateField[currState].effecter_state),
-                         entry("OBJECT_PATH=%s", objPath.c_str()));
-                     return PLDM_ERROR_INVALID_DATA;
-                 }
-                 auto dbusProp = "OperatingSystemState";
-                 std::variant<std::string> value{
-                     std::get<std::string>(iter->second)};
-                 auto dbusInterface =
-                     "xyz.openbmc_project.State.OperatingSystem.Status";
-                 try
-                 {
-                     dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
-                                              dbusInterface, value);
-                 }
-                 catch (const std::exception& e)
-                 {
-                     log<level::ERR>("Error setting property",
-                                     entry("ERROR=%s", e.what()),
-                                     entry("PROPERTY=%s", dbusProp),
-                                     entry("INTERFACE=%s", dbusInterface),
-                                     entry("PATH=%s", objPath.c_str()));
-                     return PLDM_ERROR;
-                 }
-                 return PLDM_SUCCESS;
-             }},
-            {PLDM_SYSTEM_POWER_STATE,
-             [&](const std::string& objPath, const uint8_t currState) {
-                 auto stateSet =
-                     stateNumToDbusProp.find(PLDM_SYSTEM_POWER_STATE);
-                 if (stateSet == stateNumToDbusProp.end())
-                 {
-                     log<level::ERR>("Couldn't find D-Bus mapping for "
-                                     "PLDM_SYSTEM_POWER_STATE",
-                                     entry("EFFECTER_ID=%d", effecterId));
-                     return PLDM_ERROR;
-                 }
-                 auto iter = stateSet->second.find(
-                     stateField[currState].effecter_state);
-                 if (iter == stateSet->second.end())
-                 {
-                     log<level::ERR>(
-                         "Invalid state field passed or field not "
-                         "found for PLDM_SYSTEM_POWER_STATE",
-                         entry("EFFECTER_ID=%d", effecterId),
-                         entry("FIELD=%d",
-                               stateField[currState].effecter_state),
-                         entry("OBJECT_PATH=%s", objPath.c_str()));
-                     return PLDM_ERROR_INVALID_DATA;
-                 }
-                 auto dbusProp = "RequestedPowerTransition";
-                 std::variant<std::string> value{
-                     std::get<std::string>(iter->second)};
-                 auto dbusInterface = "xyz.openbmc_project.State.Chassis";
-                 try
-                 {
-                     dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
-                                              dbusInterface, value);
-                 }
-                 catch (const std::exception& e)
-                 {
-                     log<level::ERR>("Error setting property",
-                                     entry("ERROR=%s", e.what()),
-                                     entry("PROPERTY=%s", dbusProp),
-                                     entry("INTERFACE=%s", dbusInterface),
-                                     entry("PATH=%s", objPath.c_str()));
-                     return PLDM_ERROR;
-                 }
-                 return PLDM_SUCCESS;
-             }}};
+    /** @brief Handler for GetPDR
+     *
+     *  @param[in] request - Request message payload
+     *  @param[in] payloadLength - Request payload length
+     *  @param[out] Response - Response message written here
+     */
+    Response getPDR(const pldm_msg* request, size_t payloadLength);
 
-    int rc = PLDM_SUCCESS;
-    auto paths = get(effecterId);
-    for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+    /** @brief Handler for setStateEffecterStates
+     *
+     *  @param[in] request - Request message
+     *  @param[in] payloadLength - Request payload length
+     *  @return Response - PLDM Response message
+     */
+    Response setStateEffecterStates(const pldm_msg* request,
+                                    size_t payloadLength);
+
+    /** @brief Function to set the effecter requested by pldm requester
+     *  @param[in] dBusIntf - The interface object
+     *  @param[in] effecterId - Effecter ID sent by the requester to act on
+     *  @param[in] stateField - The state field data for each of the states,
+     * equal to composite effecter count in number
+     *  @return - Success or failure in setting the states. Returns failure in
+     * terms of PLDM completion codes if atleast one state fails to be set
+     */
+    template <class DBusInterface>
+    int setStateEffecterStatesHandler(
+        const DBusInterface& dBusIntf, effecter::Id effecterId,
+        const std::vector<set_effecter_state_field>& stateField)
     {
-        std::vector<StateSetNum> allowed{};
-        // computation is based on table 79 from DSP0248 v1.1.1
-        uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
-        uint8_t bit =
-            stateField[currState].effecter_state - (8 * bitfieldIndex);
-        if (states->possible_states_size < bitfieldIndex ||
-            !(states->states[bitfieldIndex].byte & (1 << bit)))
+        using namespace std::string_literals;
+        using DBusProperty = std::variant<std::string, bool>;
+        using StateSetId = uint16_t;
+        using StateSetNum = uint8_t;
+        using PropertyMap =
+            std::map<StateSetId, std::map<StateSetNum, DBusProperty>>;
+        static const PropertyMap stateNumToDbusProp = {
+            {PLDM_BOOT_PROGRESS_STATE,
+             {{PLDM_BOOT_NOT_ACTIVE,
+               "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
+               "Standby"s},
+              {PLDM_BOOT_COMPLETED,
+               "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus."
+               "BootComplete"s}}},
+            {PLDM_SYSTEM_POWER_STATE,
+             {{PLDM_OFF_SOFT_GRACEFUL,
+               "xyz.openbmc_project.State.Chassis.Transition.Off"s}}}};
+        using namespace phosphor::logging;
+        using namespace pldm::responder::pdr;
+        using namespace pldm::responder::effecter::dbus_mapping;
+
+        state_effecter_possible_states* states = nullptr;
+        pldm_state_effecter_pdr* pdr = nullptr;
+        uint8_t compEffecterCnt = stateField.size();
+        uint32_t recordHndl{};
+        Repo& pdrRepo = get(PDR_JSONS_DIR);
+        pdr::Entry pdrEntry{};
+
+        while (!pdr)
         {
-            log<level::ERR>(
-                "Invalid state set value", entry("EFFECTER_ID=%d", effecterId),
-                entry("VALUE=%d", stateField[currState].effecter_state),
-                entry("COMPOSITE_EFFECTER_ID=%d", currState),
-                entry("DBUS_PATH=%c", paths[currState].c_str()));
-            rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
-            break;
-        }
-        auto iter = effecterToDbusEntries.find(states->state_set_id);
-        if (iter == effecterToDbusEntries.end())
-        {
-            uint16_t setId = states->state_set_id;
-            log<level::ERR>(
-                "Did not find the state set for the state effecter pdr  ",
-                entry("STATE=%d", setId), entry("EFFECTER_ID=%d", effecterId));
-            rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
-            break;
-        }
-        if (stateField[currState].set_request == PLDM_REQUEST_SET)
-        {
-            rc = iter->second(paths[currState], currState);
-            if (rc != PLDM_SUCCESS)
+            pdrEntry = pdrRepo.at(recordHndl);
+            pldm_pdr_hdr* header =
+                reinterpret_cast<pldm_pdr_hdr*>(pdrEntry.data());
+            if (header->type != PLDM_STATE_EFFECTER_PDR)
             {
+                recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
+                if (recordHndl)
+                {
+                    continue;
+                }
+                return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+            }
+            pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data());
+            recordHndl = pdr->hdr.record_handle;
+            if (pdr->effecter_id == effecterId)
+            {
+                states = reinterpret_cast<state_effecter_possible_states*>(
+                    pdr->possible_states);
+                if (compEffecterCnt > pdr->composite_effecter_count)
+                {
+                    log<level::ERR>(
+                        "The requester sent wrong composite effecter "
+                        "count for the effecter",
+                        entry("EFFECTER_ID=%d", effecterId),
+                        entry("COMP_EFF_CNT=%d", compEffecterCnt));
+                    return PLDM_ERROR_INVALID_DATA;
+                }
                 break;
             }
+            recordHndl = pdrRepo.getNextRecordHandle(recordHndl);
+            if (!recordHndl)
+            {
+                return PLDM_PLATFORM_INVALID_EFFECTER_ID;
+            }
+            pdr = nullptr;
         }
-        uint8_t* nextState =
-            reinterpret_cast<uint8_t*>(states) +
-            sizeof(state_effecter_possible_states) - sizeof(states->states) +
-            (states->possible_states_size * sizeof(states->states));
-        states = reinterpret_cast<state_effecter_possible_states*>(nextState);
-    }
-    return rc;
-}
 
+        std::map<StateSetId, std::function<int(const std::string& objPath,
+                                               const uint8_t currState)>>
+            effecterToDbusEntries = {
+                {PLDM_BOOT_PROGRESS_STATE,
+                 [&](const std::string& objPath, const uint8_t currState) {
+                     auto stateSet =
+                         stateNumToDbusProp.find(PLDM_BOOT_PROGRESS_STATE);
+                     if (stateSet == stateNumToDbusProp.end())
+                     {
+                         log<level::ERR>("Couldn't find D-Bus mapping for "
+                                         "PLDM_BOOT_PROGRESS_STATE",
+                                         entry("EFFECTER_ID=%d", effecterId));
+                         return PLDM_ERROR;
+                     }
+                     auto iter = stateSet->second.find(
+                         stateField[currState].effecter_state);
+                     if (iter == stateSet->second.end())
+                     {
+                         log<level::ERR>(
+                             "Invalid state field passed or field not "
+                             "found for PLDM_BOOT_PROGRESS_STATE",
+                             entry("EFFECTER_ID=%d", effecterId),
+                             entry("FIELD=%d",
+                                   stateField[currState].effecter_state),
+                             entry("OBJECT_PATH=%s", objPath.c_str()));
+                         return PLDM_ERROR_INVALID_DATA;
+                     }
+                     auto dbusProp = "OperatingSystemState";
+                     std::variant<std::string> value{
+                         std::get<std::string>(iter->second)};
+                     auto dbusInterface =
+                         "xyz.openbmc_project.State.OperatingSystem.Status";
+                     try
+                     {
+                         dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
+                                                  dbusInterface, value);
+                     }
+                     catch (const std::exception& e)
+                     {
+                         log<level::ERR>("Error setting property",
+                                         entry("ERROR=%s", e.what()),
+                                         entry("PROPERTY=%s", dbusProp),
+                                         entry("INTERFACE=%s", dbusInterface),
+                                         entry("PATH=%s", objPath.c_str()));
+                         return PLDM_ERROR;
+                     }
+                     return PLDM_SUCCESS;
+                 }},
+                {PLDM_SYSTEM_POWER_STATE,
+                 [&](const std::string& objPath, const uint8_t currState) {
+                     auto stateSet =
+                         stateNumToDbusProp.find(PLDM_SYSTEM_POWER_STATE);
+                     if (stateSet == stateNumToDbusProp.end())
+                     {
+                         log<level::ERR>("Couldn't find D-Bus mapping for "
+                                         "PLDM_SYSTEM_POWER_STATE",
+                                         entry("EFFECTER_ID=%d", effecterId));
+                         return PLDM_ERROR;
+                     }
+                     auto iter = stateSet->second.find(
+                         stateField[currState].effecter_state);
+                     if (iter == stateSet->second.end())
+                     {
+                         log<level::ERR>(
+                             "Invalid state field passed or field not "
+                             "found for PLDM_SYSTEM_POWER_STATE",
+                             entry("EFFECTER_ID=%d", effecterId),
+                             entry("FIELD=%d",
+                                   stateField[currState].effecter_state),
+                             entry("OBJECT_PATH=%s", objPath.c_str()));
+                         return PLDM_ERROR_INVALID_DATA;
+                     }
+                     auto dbusProp = "RequestedPowerTransition";
+                     std::variant<std::string> value{
+                         std::get<std::string>(iter->second)};
+                     auto dbusInterface = "xyz.openbmc_project.State.Chassis";
+                     try
+                     {
+                         dBusIntf.setDbusProperty(objPath.c_str(), dbusProp,
+                                                  dbusInterface, value);
+                     }
+                     catch (const std::exception& e)
+                     {
+                         log<level::ERR>("Error setting property",
+                                         entry("ERROR=%s", e.what()),
+                                         entry("PROPERTY=%s", dbusProp),
+                                         entry("INTERFACE=%s", dbusInterface),
+                                         entry("PATH=%s", objPath.c_str()));
+                         return PLDM_ERROR;
+                     }
+                     return PLDM_SUCCESS;
+                 }}};
+
+        int rc = PLDM_SUCCESS;
+        auto paths = get(effecterId);
+        for (uint8_t currState = 0; currState < compEffecterCnt; ++currState)
+        {
+            std::vector<StateSetNum> allowed{};
+            // computation is based on table 79 from DSP0248 v1.1.1
+            uint8_t bitfieldIndex = stateField[currState].effecter_state / 8;
+            uint8_t bit =
+                stateField[currState].effecter_state - (8 * bitfieldIndex);
+            if (states->possible_states_size < bitfieldIndex ||
+                !(states->states[bitfieldIndex].byte & (1 << bit)))
+            {
+                log<level::ERR>(
+                    "Invalid state set value",
+                    entry("EFFECTER_ID=%d", effecterId),
+                    entry("VALUE=%d", stateField[currState].effecter_state),
+                    entry("COMPOSITE_EFFECTER_ID=%d", currState),
+                    entry("DBUS_PATH=%c", paths[currState].c_str()));
+                rc = PLDM_PLATFORM_SET_EFFECTER_UNSUPPORTED_SENSORSTATE;
+                break;
+            }
+            auto iter = effecterToDbusEntries.find(states->state_set_id);
+            if (iter == effecterToDbusEntries.end())
+            {
+                uint16_t setId = states->state_set_id;
+                log<level::ERR>(
+                    "Did not find the state set for the state effecter pdr  ",
+                    entry("STATE=%d", setId),
+                    entry("EFFECTER_ID=%d", effecterId));
+                rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
+                break;
+            }
+            if (stateField[currState].set_request == PLDM_REQUEST_SET)
+            {
+                rc = iter->second(paths[currState], currState);
+                if (rc != PLDM_SUCCESS)
+                {
+                    break;
+                }
+            }
+            uint8_t* nextState =
+                reinterpret_cast<uint8_t*>(states) +
+                sizeof(state_effecter_possible_states) -
+                sizeof(states->states) +
+                (states->possible_states_size * sizeof(states->states));
+            states =
+                reinterpret_cast<state_effecter_possible_states*>(nextState);
+        }
+        return rc;
+    }
+};
+
+} // namespace platform
 } // namespace responder
 } // namespace pldm
