CTK框架 - 服务工厂

CTK框架 - 服务工厂

介绍

服务工厂其实就是将之前的继承的服务修改成通过服务工厂来生产服务:

服务工厂的作用:

  1. 在服务中可以知道是哪个其他插件在使用它;
  2. 懒汉式使用服务,需要的时候才new;
  3. 工厂其他插件使用有服务工厂和使用无服务工的服务,没有任何区别,代码都一样;
  4. 可根据需要创建多种实现的服务,就是:多种服务对应一个插件。

代码示例

ServiceFactory.h

#ifndef SERVICE_FACTORY_H
#define SERVICE_FACTORY_H
#include <ctkServiceFactory.h>
#include <ctkPluginConstants.h>
#include <ctkVersion.h>
#include "hello_impl.h"

class ServiceFactory : public QObject, public ctkServiceFactory
{
    Q_OBJECT
    Q_INTERFACES(ctkServiceFactory)

public:
    ServiceFactory() : m_counter(0) {}

    // 创建服务对象
    QObject* getService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration) Q_DECL_OVERRIDE {
        Q_UNUSED(registration)

        std::cout << "Create object of HelloService for: " << plugin->getSymbolicName().toStdString() << std::endl;
        m_counter++;
        std::cout << "Number of plugins using service: " << m_counter << std::endl;

        QHash<QString, QString> headers = plugin->getHeaders();
        ctkVersion version = ctkVersion::parseVersion(headers.value(ctkPluginConstants::PLUGIN_VERSION));
        QString name = headers.value(ctkPluginConstants::PLUGIN_NAME);
        std::cout << version.toString().toStdString() <<std::endl;
        QObject* hello = getHello(version);
        return hello;
    }

    // 释放服务对象
    void ungetService(QSharedPointer<ctkPlugin> plugin, ctkServiceRegistration registration, QObject* service) Q_DECL_OVERRIDE {
        Q_UNUSED(plugin)
        Q_UNUSED(registration)
        Q_UNUSED(service)

        qDebug() << "Release object of HelloService for: "  << plugin->getSymbolicName();
        m_counter--;
        qDebug() << "Number of plugins using service: "  << m_counter;
    }
private:
    // 根据不同的版本(这里是使用该服务的插件版本),获取不同的服务
    QObject* getHello(ctkVersion version) {
        if (version.toString().contains("alpha")) {
            return new HelloWorldImpl();
        } else {
            return new HelloCTKImpl();
        }
    }
private:
    int m_counter;  // 计数器
};
#endif // SERVICE_FACTORY_H

这里面的插件是使用这个服务的插件,对应的版本号也是使用服务的版本号,这个就意味着服务是根据使用方的版本号来获取相应的服务。

helloactivator.h

#ifndef HELLO_ACTIVATOR_H
#define HELLO_ACTIVATOR_H

#include <ctkPluginActivator.h>
#include <ctkPluginContext.h>
#include "hello_service.h"
#include "service_factory.h"

class HelloActivator : public QObject, public ctkPluginActivator
{
    Q_OBJECT
    Q_INTERFACES(ctkPluginActivator)
    Q_PLUGIN_METADATA(IID "Hello")

public:
    // 注册服务工厂
    void start(ctkPluginContext* context) {
        ServiceFactory *factory = new ServiceFactory();
        context->registerService<HelloService>(factory);
    }

    void stop(ctkPluginContext* context) {
        Q_UNUSED(context)
    }
};

#endif // HELLO_ACTIVATOR_H

helloimpl.h

#ifndef HELLO_IMPL_H
#define HELLO_IMPL_H

#include "hello_service.h"
#include <QObject>
#include <QtDebug>
#include <iostream>

// HelloWorld
class HelloWorldImpl : public QObject, public HelloService
{
    Q_OBJECT
    Q_INTERFACES(HelloService)

public:
    void sayHello() Q_DECL_OVERRIDE {
        std::cout << "Hello,World!" << std::endl;
    }
};

// HelloCTK
class HelloCTKImpl : public QObject, public HelloService
{
    Q_OBJECT
    Q_INTERFACES(HelloService)

public:
    void sayHello() Q_DECL_OVERRIDE {
        std::cout << "Hello,CTK!" << std::endl;
    }
};

#endif // HELLO_IMPL_H

helloservice.h

#ifndef HELLO_SERVICE_H
#define HELLO_SERVICE_H
#include <QtPlugin>
class HelloService
{
public:
    virtual ~HelloService() {}
    virtual void sayHello() = 0;
};
#define HelloService_iid "HelloService"
Q_DECLARE_INTERFACE(HelloService, HelloService_iid)
#endif // HELLO_SERVICE_H

注意: 这个我犯的一个错误,我一直以为这里获取服务的那个插件是服务提供插件本身,也就是这里的helloservice,实际上不是,实际上这里的是调用插件,比如我再Core里面调用这个服务,则这个插件是Core。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

turbolove

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值