首页 文章 精选 留言 我的

精选列表

搜索[API模拟],共10000篇文章
优秀的个人博客,低调大师

鸿蒙实战开发-使用UltimateProvider框架不写provider模拟微博页面

使用UltimateProvider框架开发的类似微博、微信朋友圈的页面。所有ListContainer的用法均使用UltimateProvider构建。 UltimateProvider框架的具体用法可参考这篇文章:UltimateProvider(适配器)简单快速的使用ListContainer而不需要写Provider。此框架是CHGAdapter的鸿蒙版本 直接看效果 框架下载地址: 安卓(CHGAdapter) Java:https://github.com/chenhaigang888/CHGAdapter_android Kotlin:https://github.com/chenhaigang888/CHGAdapter_Kotlin ios(CHGAdapter) oc:https://github.com/chenhaigang888/CHGAdapter 迅捷:https://github.com/chenhaigang888/CHGAdapter_swift HarmonyOS(UltimateProvider) java:https://github.com/chenhaigang888/UltimateProvider

优秀的个人博客,低调大师

ABAP模拟Java Spring依赖注入(Dependency injection)的一个尝试

Recently I will deliver a session regarding dependency inversion principle to my team. As Java Spring is already widely used in all other Java development teams in my site, some ABAPers are not well aware of its idea and implementation under the hood. In order for ABAPers to easily understand the mechanism of Java Spring dependency inversion, I wrote a prototype in ABAP after going through related Java source code of Spring. Before I start, I perform the search in SCN. There are already several excellent blogs written regarding dependency injection in ABAP: (1) ABAP Dependency Injection – An implementation approach(2) Shoot Me Up ABAP(3) Dependency Injection for ABAP(4) MockA in github Thanks a lot for efforts spent by authors of them!Compared with those blogs, the advantage of my prototype is: it follows exactly the design of Java Spring, it is not needed for users to do any other manual dependency registration except a single annotation @Inject. So it is useful for ABAPers to understand Spring dependency internal implementation. Let me begin with a simple example. In real world I have a switch. By pressing it, the lamp connected by that switch is turned on. With switch pressed for second time, the lamp is turned off. That’s all. Implementation without using Dependency injection I have an interface ZIF_SWITCHABLE with two simple methods: And a ZCL_LAMP which simply implements this interface: CLASS ZCL_LAMP IMPLEMENTATION. method ZIF_SWITCHABLE~OFF. WRITE: / 'lamp off'. endmethod. method ZIF_SWITCHABLE~ON. WRITE: / 'lamp on'. endmethod. ENDCLASS. And a switch which internally maintains the current switch status and a reference to ZIF_SWITCHABLE: The switch has a push method to toggle: METHOD push. IF isswitchon = abap_true. mo_switchable->off( ). isswitchon = abap_false. ELSE. mo_switchable->on( ). isswitchon = abap_true. ENDIF. ENDMETHOD. And a setter method is needed to inject the switchable instance: method SET_SWITCHABLE. mo_switchable = io_switchable. endmethod. These two classes and one interface are put to the following package: Consumer code – version one without using dependency injection Here the ZCL_SWITCH has tight dependency on ZCL_LAMP: it has to manually inject this dependency via setter method in line 11. Let’s summarize how many manual / unnecessary operations are done by consumer: (1) line 8: create lamp instance(2) line 9: create switch instance(3) line 11: connect switch with lamp Implementation using ABAP Summer I call my prototype as ABAP Summer just to show my admire on Java Spring When the same requirement is implemented in Java Spring, the logic in line 11 could completely be avoided, with help of various powerful annotation like @Autowired, @Named, @Inject etc. Thanks to Java Spring container, lots of labor work has been done by it under the hood, saving lots of routine effort from application developers so that they can only concentrate on the core business logic. For example, in Java using Spring, all developers need to do is to add annotation @Inject on top of attribute switchable – in the runtime Spring will guarantee that the annotated implementation for this interface is instantiated automatically. How can we simulate the similar logic of Spring now in ABAP Summer? (1) Add the annotation @Inject to attribute mo_switchable, which tells ABAP summer “hey, I would like this attribute to be automatically injected with proper implementation in the runtime”.Since I have no other way to add metadata in class attribute in ABAP – there is no first class annotation supported in ABAP – I have to use description field for simulation. (2) And below is my consumer code, no more manual instance initialization and manual setter call. Very clean, isn’t it? data(summer) = zcl_summer=>get_instance( ). data(lo_switch) = cast zcl_switch( summer->get_bean( EXPORTING iv_bean_name = 'ZCL_SWITCH' ) ). lo_switch->push( ). lo_switch->push( ). Let’s make comparison. By using ABAP summer, consumer can simply get switch instance from container by passing bean technical name ( here again, I use Spring terminology “bean” to name those ABAP classes which owns an injected member attribute with @Inject ). This is exactly the way a Java developer doing daily work using Java Spring: How does ABAP summer work? There are lots of books written to illustrate the design of Java Spring, I read one of them listed below, and wrote this ABAP summer based on my understanding. I draw a diagram below to explain the core method init of ABAP summer: Last by not least, when you try this demo, after you copy the source code of ZCL_SWITCH to your system and activate it, NEVER forget to add this annotation in description field manually, as in ABAP, the attribute description is not stored in source code but in DB table. More thought on ABAP annotation The annotation in Java is a form of metadata which could be defined by application developer and are available in the runtime by Java reflection. It is a built-in language feature supported by JVM. In ABAP there is no such first-class annotation supported. In CDS view, there are some grammar which have annotation-like style. You can append lots of annotation defined in SAP help to a CDS view. However those annotation are not first-class annotation supported by ABAP language itself as well. It is just CDS view framework which parses the source code of these annotation and react accordingly. For details please see these two blogs of mine: (1) My CDS view self study tutorial – Part 3 how is view source in Eclipse converted to ABAP view in the backend(2) My CDS view self study tutorial – Part 4 how does annotation @OData.publish work 本文来自云栖社区合作伙伴“汪子熙”,了解相关信息可以关注微信公众号"汪子熙"。

优秀的个人博客,低调大师

利用 es6 new.target 来对模拟抽象类

起源 最近在使用 Symbol 来做为唯一值,发现 Symbol 无法进行 new 操作,只能当作函数使用,只要进行了new 就会发生类型错误 new Symbol() // error Uncaught TypeError: Symbol is not a constructor at new Symbol (<anonymous>) at <anonymous>:1:1 在不考虑底层实现的情况下,在代码层面是否能够实现一个函数只可以进行调用而不可以进行 new 操作呢?思考之后如下写出: function disConstructor() { if (this !== window) { throw new TypeError(' disConstructor is not a constructor') } console.log('gogo go') } // 测试结果如下 disConstructor() // gogo go new disConstructor() // error Uncaught TypeError: disConstructor is not a constructor at new disConstructor (<anonymous>:3:15) at <anonymous>:1:1 如果使用 nodejs,window 可以切换为 global, 代码运行结果不变,因为对于个人而言没有适用场景。于是就没有继续研究下去,可是最近在从新翻阅 es6 时候发现 new.target这个属性。 new.target 属性 介绍(引用 mdn 文档) new.target属性允许你检测函数或构造方法是否是通过new运算符被调用的。 在通过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target 的值是undefined。 这样的话 我们的代码就可以这样改为 function disConstructor() { // 普通的函数调用中,new.target 的值是undefined。 if (new.target) { throw new TypeError(' disConstructor is not a constructor') } console.log('gogo go') } 得到与上述代码一样的答案。 深入 难道 es6 特地添加的功能仅仅只能用于检查一下我们的函数调用方式吗? 在查阅的过程各种发现了大多数都方案都是用 new.target 写出只能被继承的类。类似于实现java的抽象类。 class Animal { constructor(name, age) { if (new.target === Animal) { throw new Error('Animal class can`t instantiate'); } this.name = name this.age = age } // 其他代码 ... } class Dog extends Animal{ constructor(name, age, sex) { super(name, age) this.sex = sex } } new Animal() // error Uncaught Error: Animal class can`t instantiate at new Animal (<anonymous>:4:13) at <anonymous>:1:1 new Dog('mimi', 12, '公') // Dog{name: "mimi", age: 12, sex: "公"} 但是 java抽象类抽象方法需要重写,这个是没有方案的。于是在测试与使用的过程中,却意外发现了超类可以在构造期间访问派生类的原型,利用起来。 class Animal { constructor(name, age) { console.log(new.target.prototype) } // 其他代码 ... } 之前运行时调用需要重写的方法报错是这样写的。 class Animal { constructor(name, age) { this.name = name this.age = age } getName () { throw new Error('please overwrite getName method') } } class Dog extends Animal{ constructor(name, age, sex) { super(name, age) this.sex = sex } } const pite = new Dog('pite', 2, '公') a.getName() // error Uncaught Error: please overwrite getName method at Dog.getName (<anonymous>:8:11) at <anonymous>:1:3 然而此时利用 new.target ,我就可以利用 构造期间 对子类进行操作报错。 class Animal { constructor(name, age) { // 如果 target 不是 基类 且 没有 getName 报错 if (new.target !== Animal && !new.target.prototype.hasOwnProperty('getName')) { throw new Error('please overwrite getName method') } this.name = name this.age = age } } class Dog extends Animal{ constructor(name, age, sex) { super(name, age) this.sex = sex } } const pite = new Dog('pite', 2, '公') // error Uncaught Error: please overwrite getName method at new Animal (<anonymous>:5:13) at new Dog (<anonymous>:14:5) at <anonymous>:1:1 此时可以把运行方法时候发生的错误提前到构造时期,虽然都是在运行期,但是该错误触发机制要早危害要大。反而对代码是一种保护。 当然了,利用超类可以在构造期间访问派生类的原型作用远远不是那么简单,必然是很强大的,可以结合业务场景谈一谈理解和作用。 其他方案 增加 编辑器插件 proxy 修饰器

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册