文章目录
CTK框架 - 服务工厂
介绍
服务工厂其实就是将之前的继承的服务修改成通过服务工厂来生产服务:
服务工厂的作用:
- 在服务中可以知道是哪个其他插件在使用它;
- 懒汉式使用服务,需要的时候才new;
- 工厂其他插件使用有服务工厂和使用无服务工的服务,没有任何区别,代码都一样;
- 可根据需要创建多种实现的服务,就是:多种服务对应一个插件。
代码示例
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。