我正在编写的C++ MVC框架大量使用了观察者模式.我已经详细阅读了设计模式(GoF,1995)中的相关章节,并了解了文章和现有库(包括Boost)中的大量实现.
但是当我实现这个模式时,我无法理解必须有一个更好的方法 - 我的客户端代码涉及线条和片段,我认为它应该被重构到模式本身,只要我能找到克服的方法一些C++限制.此外,我的语法从未像ExtJs库中那样优雅:
// Subscribing
myGridPanel.on( 'render', this.onRender );
// Firing
this.fireEvent( 'render', null, node );
Run Code Online (Sandbox Code Playgroud)
所以我决定进行进一步的研究,试图达到一个通用的实现,同时优先考虑代码的优点,可读性和性能.我相信我在第5次尝试中获得了累积奖金.
名为的实际实现gxObserver可在GitHub上获得; 它是完整的文档和自述文件拼写出来的优点和缺点.它的语法是:
// Subscribing
mSubject->gxSubscribe( evAge, OnAgeChanged );
// Firing
Fire( evAge, 69 );
Run Code Online (Sandbox Code Playgroud)
做了过度工作后,我觉得只是与SO社区分享我的发现.所以下面我将回答这个问题:
在实现观察者模式时,程序员应该考虑哪些额外的考虑(设计模式中提供的那些)?
虽然专注于C++,但下面的许多内容将适用于任何语言.
请注意:由于SO限制了30000个单词的答案,我的答案必须分为两部分,但有时候第二个答案(首先是"主题"出现的答案).答案的第1部分是从Design Patterns的类图开始的答案.
我想写一个javascript库(框架),但需要OOP和mixins.
是打算使用打字稿,但它不支持mixins(手册说它确实如此,但编译器/规范没有任何与mixin相关的东西).
在typescript中,以下代码:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
Run Code Online (Sandbox Code Playgroud)
编译为:
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
Run Code Online (Sandbox Code Playgroud)
然后客户可以简单地致电:
var greeter = new Greeter("world");
Run Code Online (Sandbox Code Playgroud)
飞镖可以做类似的事吗?有人能说明怎么样?
主要目标是生成的javascript代码是可读的,最好是所有的dart extras驻留在不同的脚本中.
我正在创建一个更改日志,我决定从.html文件加载我的更改日志
我有
Ext.define('MeridianCRM.dialogs.recent?hanges.recent?hanges', {
extend : 'Ext.window.Window',
title : '????????? ????????? ?? ?????',
modal : true,
height : 400,
width : 500,
resizable : false,
html: 'changes.html',
buttons: [{
text: '???????',
handler: function() {
this.up('window').close();
}
}]
});
Run Code Online (Sandbox Code Playgroud)
我怎么能解决这个问题?(html:'changes.html')如何将html加载到我的窗口?
每次我开玩笑时,它什么也不会运行。我让柜台任意高。我用--no-cache开玩笑
jest --debug输出如下:
{
"configs": [
{
"automock": false,
"browser": false,
"cache": true,
"cacheDirectory": "/var/folders/7v/64n1tsk11zs2pbwf5bm_c9kc0000gn/T/jest_dx",
"clearMocks": false,
"coveragePathIgnorePatterns": [
"/node_modules/"
],
"detectLeaks": false,
"forceCoverageMatch": [],
"globals": {},
"haste": {
"defaultPlatform": "ios",
"platforms": [
"android",
"ios",
"native"
],
"providesModuleNodeModules": [
"react-native"
]
},
"moduleDirectories": [
"node_modules"
],
"moduleFileExtensions": [
"js",
"json",
"jsx",
"node"
],
"moduleNameMapper": [
[
"^React$",
"/Users/skilurus/github/flock-react-app/node_modules/react"
]
],
"modulePathIgnorePatterns": [
"/Users/skilurus/github/flock-react-app/node_modules/react-native/Libraries/react-native/"
],
"name": "b29a126b130a0be47202d3bc7b00f1b4",
"resetMocks": false,
"resetModules": false,
"restoreMocks": false,
"rootDir": "/Users/skilurus/github/flock-react-app",
"roots": [
"/Users/skilurus/github/flock-react-app"
],
"runner": "jest-runner", …Run Code Online (Sandbox Code Playgroud) Ramdatransduce可以创建惰性序列。
R.chain可以在转换器中用作一对多运算符,如下所示(REPL):
const tapLog = R.tap( (what) => console.log(what) )
const suits = ['?', '?', '?', '?']
const ranks = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'J', 'Q', 'K', 'A']
const addRank = (suit) => R.map(concat(suit),ranks)
var transducer = R.compose(
R.chain(addRank),
tapLog,
R.take(2)
);
R.into([], transducer, suits);
// => ?1 // console.log
// => ?2 // console.log
// => ["?1", "?2"]
Run Code Online (Sandbox Code Playgroud)
上面代码片段的问题是它R.map(concat(suit),ranks)不会是懒惰的——所有的等级都将被映射(创建中间阵列),只有这样链才会将它们一个一个地“管道”到传感器序列中。
这不是问题,除非您要映射 680k …
我正在创建一个extjs网格面板,它具有一组用户可配置的列.该Ext.grid.Panel组件reconfigure(store, columns)为此提供了一种方便的方法.
此方法按预期工作,无需完全销毁和重新创建网格,即可重新配置网格的存储/列.但是,如果您使用Ext.grid.plugins.RowEditing插件提供内联行编辑,则在使用新列重新配置网格后,列将不同步.
这特别令人沮丧,因为RowEditing插件已经监视添加/删除/调整列并正确处理这些列.我怀疑这只是当前版本的ExtJs的疏忽.
我想要的是RowEditor在使用新列重新配置网格时更新其编辑器列表和宽度,而不会破坏/重新创建网格/视图.
经过大量的谷歌搜索后,看起来我并不是唯一一个寻找具有内联编辑支持的易于重新配置的列列表的人.
在开发过程中,我正在使用karma和grunt来监视文件更改并运行测试.
在命令行中,我希望能够简单地输入
$ grunt watch
Run Code Online (Sandbox Code Playgroud)
让业力服务器启动一次,然后每当文件发生变化时,咕噜咕噜地看着变化并运行各种任务(包括业力测试).我不想进入$ karma start.
怎么能实现这一目标?
我有一个像下面这样的JSON数据.
{
"divisions": [{
"name": "division1",
"id": "div1",
"subdivisions": [{
"name": "Sub1Div1",
"id": "div1sub1",
"schemes": [{
"name": "Scheme1",
"id": "scheme1"
}, {
"name": "Scheme2",
"id": "scheme2"
}]
}, {
"name": "Sub2Div1",
"id": "div1sub2",
"schemes": [{
"name": "Scheme3",
"id": "scheme3"
}]
}
]
}]
}
Run Code Online (Sandbox Code Playgroud)
我想读入TreeStore这一点,但不能改变的子域(divisions,subdivisions,schemes)是相同的(例如,children).
怎么能实现我这个?
如何当一个让连续调用到HTML5画布的行为clip(),translate()还是scale()?
我有一个javascript客户端将参数传递给服务器函数(我正在使用ExtJS Direct).有时客户端发送一个对象,有时它会发送一个对象数组.
目前我正在使用这个EnsureArray函数来确保参数是一个数组,然后我这样做foreach:
// Wraps a non array variable with an array.
function EnsureArray( &$aVar )
{
if ( !is_array( $aVar ) )
$var = array( $aVar );
}
function Destroy( $aRecords )
{
// $aRecords might be a single object or an array of objects. Ensure it's wrapped as an array.
$this->EnsureArray( $aRecords );
foreach ( $aRecords as $aRecord )
{
sql( "UPDATE Groups SET deleted = true WHERE id = $aRecord->id LIMIT 1" );
}
return …Run Code Online (Sandbox Code Playgroud) 我是ExtJs的新手.获取面板html内容时,我一直面临着面板问题.
xtype : 'panel',
id : 'first_block',
html : '<p>Hi this is belongs to first block.</p>',
listeners : {
render : function(c) {
c.body.on('click', function() {
alert('' + this.id);
alert(Ext.getCmp('first_block').items.getAt(0).getValue());
});
}
Run Code Online (Sandbox Code Playgroud)
我没有得到HTML内容,但我得到像"first_block-body"的id.
提前致谢.
我正在尝试重载==运算符来比较两个对象.由于某种原因,永远不会调用重载的处理程序.
class gxCallback
{
public:
virtual bool operator==(const gxCallback &aOther) const
{
// This is never called
return true;
}
};
typedef std::vector < gxCallback* > CallbackList;
void gxObservable::Fire( gxCallback *aCallback )
{
CallbackList::iterator iCallback;
for ( iCallback = mCallbacks.begin(); iCallback != mCallbacks.end(); ++iCallback )
{
if ( aCallback == *iCallback ) // The comparison is never made via the overloaded ==
{
// Do something
}
}
}
Run Code Online (Sandbox Code Playgroud)