功能与API的分离封装

功能与API的分离封装

原始需求

Python中的一个类封装了各种操作,需要对外提供组合各种操作的接口,为了将操作与接口分开,且易于扩展。

  • 操作与接口分开:Process类与Api类。Process封装操作内容,Api类对操作进行组合
  • 易于扩展:Process::parse()中的apis添加了操作名称与对应函数的映射。parse()也可以移动到Api类中。添加新接口时只需在Api类中添加对应的函数、apis中添加名称映射即可。

不知道是不是某个设计模式(类似于某个工厂模式,不过应该不算是吧)。
Python支持动态绑定,可以嵌套生成,不嵌套调用就行。
用C++简单实现了一下,list跟map创建比较麻烦,坑也比较多。例子粗糙,但基本功能已经实现。

  • pyhton
class Process(object):
    def __init__(self, api):
        self.__api = api
        self.__hello = 'hello'
        self.__world = 'world'

    def hello(self):
        return self.__hello

    def world(self):
        return self.__world

    def parse(self, args):
        apis = {
    
    'hello_world': self.__api.hello_world, 'world_hello': self.__api.world_hello}
        for arg in args:
            if arg in apis:
                apis[arg]()
            else:
                print('找不到命令:{}'.format(arg))


class Api(object):
    def __init__(self):
        self.__process = Process(self)

    def hello_world(self):
        print('{} {}'.format(self.__process.hello(), self.__process.world()))

    def world_hello(self):
        print('{} {}'.format(self.__process.world(), self.__process.hello()))

    def run(self):
        args = ['hello_world', 'world_hello', 'HelloWorld']
        self.__process.parse(args=args)


api = Api()
api.run()
  • c++
// $ g++ process.cpp -o ./process --std=c++11 -g
// $ ./process                                  
// hello world
// Api::~Api() _process : 0x0x7fab2f705b70
// world hello
// Api::~Api() _process : 0x0x7fab2f705b70
// 找不到命令:HelloWorld
// Api::~Api() _process : 0x0x7fab2f705b70

#include <iostream>
#include <list>
#include <map>
#include <functional>  // bind
using namespace std;

class Api;

class Process
{
    
    
public:
    Process(const Api*api):_api(api){
    
    }
    const string& hello() {
    
    
        return _hello;
    }
    const string& world() {
    
    
        return _world;
    }
    void parse(const list<string>&options);
private:
    const Api *_api;
    const string _hello = "hello";
    const string _world = "world";
};

class Api
{
    
    
public:
    Api() {
    
    
        _process = new Process(this);
    }
    ~Api() {
    
    
        cout << "Api::~Api() _process : 0x" << hex << (void*)_process << endl;
    }
    void hello_world() {
    
    
        cout << _process->hello() << " " << _process->world() << endl;
    }
    void world_hello() {
    
    
        cout << _process->world() << " " << _process->hello() << endl;
    }
    void run() {
    
    
        const list<string> options = {
    
    "hello_world", "world_hello", "HelloWorld"};
        _process->parse(options);
    }
private:
    Process *_process = nullptr;
};

inline void Process::parse(const list<string>&options) {
    
    
    auto ra1 = &Api::hello_world;
    auto ra2 = &Api::world_hello;
    map<string, decltype(ra1)> kv;
    kv.insert(make_pair(string("hello_world"), ra1));
    kv.insert(make_pair(string("world_hello"), ra2));
    for(auto option:options) {
    
    
        auto itea = kv.find(option);
        if(itea != kv.end()) {
    
    
            auto bd = bind((*itea).second, *_api);
            bd();  // Api::~Api()
        }
        else{
    
    
            cout << "找不到命令:" << option << endl;
        }
    }
}

int main() {
    
    
    Api api;
    api.run();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u012101384/article/details/129284404