Giter VIP home page Giter VIP logo

protocolservicekit's Introduction

ProtocolServiceKit

Version License Platform

东半球最高效的 Protocol<=>Service 中间件,解决中间件的占用内存问题。

  • Support:ObjC/Swift项目(纯OC/Swift/混编)均可使用
  • Map && Cache
  • SafeMode

完善的中间件组件化示例工程

  • Use Example【Swift /ObjC】

Q&A

  • 引入此中间件,如何完全解耦?(见下文)
  • 使用此组件,是否可以代码提醒函数功能?

业界常用的组件通信方案

URL Router

蘑菇街路线

  • 优点:方案成熟,极高的动态性,能解决组件依赖 ,易于适配 URL Scheme
    • 可多端复用 (方便地统一管理多平台的路由规则) ✅
  • 缺点:需要注册维护URL表,编译阶段无法发现潜在BUG 🙅‍♂️
    • 注册存在内存占用问题
    • 传参方式有限,并且无法利用编译器进行参数类型检查,因此所有的参数都只能从字符串中转换而来
      • 参数可以通过 protocol 直接传递,能够利用编译器检查参数类型,并且在 ZIKRouter 中,能通过路由声明和编译检查。
    • 要让 view controller 支持 url,需要为其新增初始化方法,因此需要对模块做出修改
      • 不支持 storyboard
    • 无法明确声明模块提供的接口,只能依赖于接口文档,重构时无法确保修改正确
    • 无法保证所使用的模块一定存在
    • 解耦能力有限,url 的"注册"、"实现"、"使用"必须用相同的字符规则,一旦任何一方做出修改都会导致其他方的代码失效,并且重构难度大

Target-Action

  • 优点:不需要注册和内存占用 ✅

  • 缺点:编译阶段无法发现潜在BUG,必须遵守命名规则 🙅‍♂️

    • 在 category 中仍然引入了字符串硬编码,内部使用字典传参,一定程度上也存在和 URL 路由相同的问题
      • 字典传参的问题
    • 无法保证所使用的模块一定存在,target 模块在修改后,使用者只有在运行时才能发现错误
    • 过于依赖 runtime 特性,无法应用到纯 Swift 上。在 Swift 中扩展 mediator 时,无法使用纯 Swift 类型的参数
    • 可能会创建过多的 target 类
    • 使用 runtime 相关的接口调用任意类的任意方法,需要注意别被苹果的审核误伤。

Protocol-Class

  • 优点:接口与实现分离,编译阶段就能发现问题 ✅

  • 缺点:需要注册和内存占用。

    • 由框架来创建所有对象,创建方式有限,例如不支持外部传入参数,再调用自定义初始化方法
    • 只做了 protocol 和 class 的匹配,不支持更复杂的创建方式和依赖注入
    • 无法保证所使用的 protocol 一定存在对应的模块,也无法直接判断某个 protocol 是否能用于获取模块。

ProtocolServiceKit

基于Protocol-Class方案

  • 优点:同上Protocol-Class方案,但移除了注册逻辑,解决占用内存问题及Protocol对应ServiceClass存在性安全校验。

  • Map

    • 1.2.0 + Support
    • 可以不按照约定规则来提供ServiceClass,项目初始化/需要处提供map表机制,解决强制命名类规范问题,可自由自定义IMPClass。
  • Cache

    • 1.3.0 + Support。
    • 建议项目最常用到组件ProtocolService使用。
    • Kit内部维护一张表,快速查找到对应的ServiceClass。
  • 安全模式

    对外业务能力如果未实现,运行期调用会触发断言处,便于发现问题 ✅

    • 1.6.0 + (推荐2.1.0+) Support ✅
    • 可选择关闭。但不推荐忽略安全模式手动关闭,便于及时发现问题。
  • 部分缺点同上Protocol-Class

Installation

ProtocolServiceKit is available through cocoapods. To install it, simply add the following line to your Podfile:

// OC项目建议参考下行
pod 'ProtocolServiceKit',"~>2.2.1"  # Default is ObjC

// Swift项目建议参考下行
pod 'ProtocolServiceKit/Swift',"~>2.2.1" 

// deprecate
pod 'ProtocolServiceManger',"~>1.0.0"

ObjC Example

To run the example/SwiftExample project, clone the repo, and run pod install from the Example directory first.

为了方便理解,AccountBusiness和PlayBusiness 已部署为远端示例组件,仅暴露Protocol文件

Main API

- (Class)serviceClassWithProtocol:(Protocol *)aProtocol;

- (Class)serviceClassWithCachedProtocol:(Protocol *)cachedProtocol;

- (void)configProtocolServiceMapsWithDic:(NSDictionary < NSString * ,NSString *> *)mapDics;
  • AccountBusiness <=> PlayBusiness Example
// VIP和播放业务复杂后,只公开Protocol文件决定业务对外能力
// ServiceWithCachedProtocol 缓存使用

Class <LFLVipProtocol> vipService = ServiceWithProtocol(LFLVipProtocol);

// 不直接使用对应账户类  [LFLAccountTool isUserVipStatus];

BOOL isVip = [vipService isCurrentUserVipStatus];

if (vipService && isVip) {
   [ServiceWithCachedProtocol(LFLPlayProtocol) playMiniVideo];
} else {
   NSLog(@"Error:LFLVipProtocol notfound service Class");
}
/// Default  Value NO 【setting YES,ignore All Error Type 】
@property (nonatomic,assign)BOOL ignoreSafeMode;
  • recommended convention

    • XXXService

    • XXXProtocol

  • 项目已存在或者想自由风格命名:Map解决方案

NSDictionary *mapDic = @{
    @"LFLUnRuleProtocol":@"LFLTestRuleIMP"
};
[[ProService sharedManger] configProtocolServiceMapsWithDic:mapDic];

Swift Example

  • ProtocolServiceKit.ProService

  • Swift版本有代码提示!

import ProtocolServiceKit.ProService

 func ProtocolServiceNormalDemo() {
        
        // 1.1 use
        let normalService : AnyClass = ProtocolService.serviceClass(aProtocol: SwiftNormalProtocol.self)
        
        // 1.2 Xcode can tip functions
        
        normalService.normalFunction()
        
        // 1.3 cache Service Class
        let normalCacheServiceDemo : AnyClass = ProtocolService.serviceCacheClass(aProtocol: SwiftNormalProtocol.self)
        normalCacheServiceDemo.normalFunction()
        
        // 2.0 recommend most use Example
        let normalCacheService : AnyClass = ProtocolService.serviceCacheClass(aProtocol: SwiftNormalProtocol.self)
        
        normalCacheService.normalFunction()
        
    }
    
    func ProtocolServiceMapDemo() {
        ProtocolService.configProtocolServiceMaps(mapDic: ["MapExampleProtocol":"MapUnRuleClass"], nameSpace: "SwiftExample")
        
        let mapCacheService : AnyClass = ProtocolService.serviceCacheClass(aProtocol: MapExampleProtocol.self)
        mapCacheService.MapExampleFunction()
    }

Q&A

建议组件之间通过明确的API接口交互,如果需要完全隔离(Example:A组件和B组件交互,不可以相互引用)

  • 对于接口层可以单独为轻量级组件(A和B业务组件均存在对应附属的协议层组件A-Protocol,B-Protocol)即可

使用此组件,是否可以代码提醒函数功能?

一般不建议使用此版本 [ branch Function]

  • 支持对象函数调用提醒
// OC项目建议参考下行
pod 'ProtocolServiceKit', :git => 'https://github.com/DevDragonLi/ProtocolServiceKit.git', :branch => 'tipFunction' # Default is ObjC
// Swift项目建议参考下行
pod 'ProtocolServiceKit/Swift', :git => 'https://github.com/DevDragonLi/ProtocolServiceKit.git', :branch => 'tipFunction' 

扩展:对于协议类可抽象出基类协议解决异常Case【视项目而定】

  • 无实现的API最终兜底方案。

Author

DevdragonLi, [email protected]

License

ProtocolServiceKit is available under the MIT license. See the LICENSE file for more info.

protocolservicekit's People

Contributors

devdragonli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

protocolservicekit's Issues

内部通过异步并行队列执行注册操作,多次注册同一个协议实现类时存在隐患。

通过如下代码多次注册协议实现类时存在隐患,可能产生脏数据:
`
for (int idx = 0; idx < 5; idx++) {

    NSArray *clzNameArr = @[@"LFLImp1", @"LFLImp2", @"LFLImp3", @"LFLImp4", @"LFLImp5"];
    
    for (NSString *clzName in clzNameArr) {
        [[ProService sharedManger] configProtocolServiceMapsWithDic:@{
            @"LFLUnRuleProtocol" : clzName
        }];
    }
        
    Class clz = ServiceWithProtocol(LFLUnRuleProtocol);
    NSLog(@"第%d次注册, 注册类名: %@", idx + 1, NSStringFromClass(clz));
}

`

输出:

2020-11-23 16:23:05.907336+0800 ProtocolServiceManger_Example[63550:522486] 第1次注册, 注册类名: LFLImp2 2020-11-23 16:23:05.907472+0800 ProtocolServiceManger_Example[63550:522486] 第2次注册, 注册类名: LFLImp1 2020-11-23 16:23:05.907584+0800 ProtocolServiceManger_Example[63550:522486] 第3次注册, 注册类名: LFLImp1 2020-11-23 16:23:05.907703+0800 ProtocolServiceManger_Example[63550:522486] 第4次注册, 注册类名: LFLImp3 2020-11-23 16:23:05.907840+0800 ProtocolServiceManger_Example[63550:522486] 第5次注册, 注册类名: LFLImp1 2020-11-23 16:23:05.909481+0800 ProtocolServiceManger_Example[63550:522486] 协议为:LFLUnRuleProtocol,实际实现类为LFLImp4

推荐做线程安全处理。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.