मेरे पास उत्तर नामक एक वर्ग प्रकार था, इसका रूप इस प्रकार है:

class reply {
public:
    enum class type {
        error = 0,
        bulk_string = 1,
        simple_string = 2,
        null = 3,
        integer = 4,
        array = 5
    };
public:
    type get_type(void) const {
        return type_;
    }
private:
    type type_;
};

उत्तर उदाहरण अन्य कार्यों द्वारा वापस किया जाएगा, इसलिए मैं get_type की कॉल के प्रत्येक संभावित मूल्य की जांच के साथ उत्तर से निपटूंगा। पहला समाधान स्विच केस का उपयोग करना है, लेकिन मैं इसे 'ओओपी' सोच का उपयोग करके निम्नानुसार समाहित करना चाहता हूं:

template<typename Handlers, typename Handlers::type*...types>
class handlers {
private:
    static constexpr typename Handlers::type* dealers[] = { types... };
public:
    static void deal(const reply& reply) {
        dealers[int(reply.get_type())](reply);
    }
};

template<typename Handlers>
class handle{
public:
    using handles = handlers<Handlers, Handlers::error_handle,
        Handlers::bulk_string_handle, Handlers::simple_string_handle,
        Handlers::null_handle, Handlers::integer_handle,
        Handlers::array_handle>;
};
class handler
{
  
public:
    static void error_handle(const reply&) {
        std::cout << "error_handle" << std::endl;
    }
    static void bulk_string_handle(const reply&) {
        std::cout << "bulk_string_handle" << std::endl;
    }
    static void simple_string_handle(const reply&) {
        std::cout << "simple_string_handle" << std::endl;
    }
    static void null_handle(const reply&) {
        std::cout << "null_handle" << std::endl;
    }
    static void integer_handle(const reply&) {
        std::cout << "integer_handle" << std::endl;
    }
    static void array_handle(const reply&) {
        std::cout << "array_handle" << std::endl;
    }
public:
    using type = decltype(error_handle);
    using handles = handle<handler>::handles;
};

अंत में, मैं इस तरह उत्तर का सौदा कर सकता हूं:

int main() 
{
   
    reply rep;
    handler::handles::deal(rep);
    return 0;
}

नोट: प्रत्येक उत्तर का अपना हैंडलर होता है। मैं इस बात पर ध्यान केंद्रित करता हूं कि क्या समाधान के अनुकूल होने का बेहतर तरीका है?

c++
1
Keanyuan 2 नवम्बर 2020, 12:43

1 उत्तर

सबसे बढ़िया उत्तर

यथासंभव कम से कम "केंद्रीय बिंदु" डिज़ाइन करें। नए उत्तर प्रकारों को जोड़ना आसान बनाने पर ध्यान केंद्रित करें, डिज़ाइन उस धारणा से प्रवाहित होगा। हैंडलर को चुनने वाले एक केंद्रीय बिंदु के साथ प्रत्येक उत्तर से जुड़े अलग-अलग हिस्से बनाएं। केंद्रीय बिंदु को एक कारखाना कहा जाता है और छोटे हिस्से समान इंटरफ़ेस को लागू करते हैं।

struct handler {
    // I do not know, maybe this should store the reply?
    // No idea.
    virtual void handle(const reply&);
    virtual ~handler();
};

struct error_handler : handler {
    void handle(const reply&) { /* blabla */ }
    handler construct() { return error_handler(); }
};
/* etc. for each handle type */

// TODO: convert to static array to save dynamic allocatiosn
std::map<std::reply::type, std::function<handler()>> handlers_map{
     { std::reply::error, []() { return error_handler(); } },
     /* etc. for each handle type */
};
handler handler_factor(const reply& r) {
      return handlers_map.at(r.get_type())();
}

#if YAY_AN_ARRAY // an example of converting map to a static array
// TODO: do it as a member function
static handler error_handler_construct() { return error_handler(); }
static std::array<handler (*)(), 1> handlers_array{
        &error_handler_construct,
        /* etc. */
};
handler handler_factor(const reply &r) {
        // remember about error handling
        return handlers_array.at(
           static_cast<int>(r.get_type())
        )();
}
#elif YAY_ANOTHER_ARRAY
static handler (*const handlers_array[])() = {
      [static_cast<int>(reply::type::error)] = &error_handler_construct,
      /* etc. */
};
handler handler_factor(const reply &r) {
       auto t = static_cast<int>(r.get_type();
       if (t < 0 || t > sizeof(handlers_array)/sizeof(*handlers_array)) {
            abort();
       }
       return handlers_array[t]();
}
#enidf

int main() {
   reply rep;
   auto h = handler_factor(rep);
   h.handle(rep);
   return 0;
}
0
KamilCuk 2 नवम्बर 2020, 12:22