CTK框架 - 服务工厂

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

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。

目录
相关文章
|
5月前
|
存储 XML Java
探索Java常用的包:从核心到扩展
探索Java常用的包:从核心到扩展
96 3
|
设计模式
实现生成工厂代码,实现热加载
实现生成工厂代码,实现热加载
C++插件管理类(下)——实际项目(阉割版)
C++插件管理类(下)——实际项目(阉割版)
84 0
CTK框架 - 通信 - 插件服务注册和调用
接口就是虚函数(也可以是纯虚函数),也就是最终的服务的前身。 接口对外暴露功能,比如我们给之前写的mainwindow 加一个界面类,并且对外暴露一个popWindow()的接口
136 0
|
JSON API 数据格式
.net core工具组件系列之Autofac—— 第一篇:Autofac系列Autofac的几种常见注册方式、生命周期和AOP
使用Autofac进行服务注册实践:新建三个项目,分别是webapi项目 Wesky.Core.Autofac以及两个类库项目 Wesky.Core.Interface和Wesky.Core.Service。在Webapi项目下,引用Autofac的三个包:Autofac、Autofac.Configuration和Autofac.Extensions.DependencyInjection 。
1346 1
.net core工具组件系列之Autofac—— 第一篇:Autofac系列Autofac的几种常见注册方式、生命周期和AOP
|
运维 监控
JPOM - Plugin插件工厂机制
JPOM - Plugin插件工厂机制
87 0
|
存储 运维 Dubbo
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
> Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双 11 基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。 > 本文
484 0
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
|
Web App开发
skyline6:二次开发web工程调用网络fly文件
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bitree1/article/details/79241376 1.web工程调用网络fly文件 (1)新建一个空的web工程,并在工程中新建一个HTML页面,将页面分成左右结构,并将skyline的相关对象引入到页面中,如下图所示: 备注:上图中的各OBJECT对象从“TerraExplorer Pro”软件中的程序开发指南中复制。
1394 0