当前位置: 首页 > wzjs >正文

沧州大型网站建设英文网站建设服务合同模板下载

沧州大型网站建设,英文网站建设服务合同模板下载,如何建设网站济南兴田德润团队怎么样,腾讯游戏推广代理加盟插件架构(微内核架构) 支持软件能力可扩展、可定制 核心概念: 内核:作为应用入口(主体),提供基础服务、插件调度、事件中心等等插件:实现标准的初始化、启动、关闭等标准接口&…

插件架构(微内核架构)

支持软件能力可扩展、可定制

核心概念:

  1. 内核:作为应用入口(主体),提供基础服务、插件调度、事件中心等等
  2. 插件:实现标准的初始化、启动、关闭等标准接口,实现插件的生命周期管理
  3. 插件接口(插件注册机制):插件接入内核的方式
  4. 上下文信息:在插件间传递的共享数据

三种插件模式

常用以下三种插件模式:管道式、洋葱式和事件式,

管道式插件设计

  1. 比如 命令行cat file.txt | grep "keyword"
  2. 比如 Gulp:
gulp.task("css", [], function () {return gulp.src(["src/css/**/*.less"]).pipe(less()).pipe(minifyCss()).pipe(concat("app.css"));
});

缺点:容易出现单点故障。顺序设计复杂,确保数据流的正确和有效需要仔细管理。

洋葱式插件设计

比如 Nodejs 中间件,参考 koa-compose

特点: 可处理输入流和输出流,但层次嵌套设计提高了应用复杂度。

事件式插件设计

比如 vscode 插件系统、chrome 扩展插件、webpack 插件机制等

事件模式插件实践

flow 编辑器设计示例

Kernel 设计
//节点schema定义
interface NodeSchema{//基础属性,比如name,icon等id,//节点组件、表单schema、表单数据预检、转换等部分node,//edge组件、表单schema等edge,
}
// 操作schema定义
interface OperationSchema {id,//基础属性,比如name,icon等meta: {name,icon,visibility: ["toolbar", "contextmenu"],execute: ({ selectedNodes, kernel,...rest }) => void,}// 插件激活方法,注册时调用activate(kernel) {},deactivate(kernel) {},
}
// 内核
class FlowKernel {//节点nodes: NodeTypeRegistry;//操作ops: OperationRegistry;//设置config: ConfigManager;//事件中心events: EventBus;//快捷键hotkeys:HotkeyManager;//省略其他属性...constructor() {this.nodes = new NodeTypeRegistry(this);this.ops = new OperationRegistry(this);this.config = new ConfigManager();this.events = new EventBus();this.hotkeys = new HotkeyManager();// 加载基础节点/插件 结构示例this.registerNode(DefaultNode);this.registerOperation(DefaultOperation);//...}registerNode(node: NodeMeta) {this.nodes.register(node);}registerOperation(plugin: Plugin) {this.ops.register(plugin);plugin.activate?.(this);}
}
class NodeTypeRegistry {private types = new Map<string, NodeMeta>();constructor(private kernel: FlowKernel) {}register(type: NodeMeta) {this.types.set(type.id, {component: type.component,defaultConfig: type.defaultConfig,formSchema: type.formSchema // 动态表单定义});}getFormSchema(nodeType: string) {return this.types.get(nodeType)?.formSchema;}
}class OperationRegistry {private operations = new Map<string, OperationMeta>();register(op: OperationMeta) {this.operations.set(op.id, {...op.meta,visibility: op.meta.visibility||['toolbar','contextmenu']});}getVisibleOperations(location: 'toolbar' | 'contextmenu') {return Array.from(this.operations.values()).filter(op => op.visibility.includes(location));}
}class EventBus {private listeners = new Map<string, (...args: any[]) => void>();on(event: string, listener: (...args: any[]) => void) {if (!this.listeners.has(event)) {this.listeners.set(event, listener);}}emit(event: string, ...args: any[]) {if (this.listeners.has(event)) {this.listeners.get(event)(...args);}}
}class ConfigManager {private config = {//主题色theme:{}operations: {//比如:控制菜单是否在上下文可见'copy': { visibleInContextMenu: true }},};updateOperationConfig(opId: string, config: object) {this.config.operations[opId] = config;}getOperationVisibility(opId: string) {return this.config.operations[opId]?.visibleInContextMenu ?? false;}
}
UI 集成:
  • 节点面板:
function NodePalette({ kernel }: { kernel: FlowKernel }) {const nodes = useMemo(() => Array.from(kernel.nodes.types.values()),[kernel]);return (<div className="node-palette">{nodes.map((node) => (<DraggableNode nodeSchema={node} />))}</div>);
}
  • 工具栏
function Toolbar({ kernel }: { kernel: FlowKernel }) {const operations = useMemo(() => kernel.ops.getVisibleOperations("toolbar"),[kernel]);return (<div className="toolbar">{operations.map((op) => (<OpButtonkey={op.id}onClick={() => op.execute()}icon={op.icon}name={op.name}/>))}</div>);
}
  • 上下文菜单
function useContextMenu(kernel: FlowKernel) {const [menuItems, setItems] = useState<OperationMeta[]>([]);useEffect(() => {const handler = (position: { x: number; y: number }) => {setItems(kernel.ops.getVisibleOperations('contextmenu'));};//每次显示菜单时,更新菜单项kernel.events.on('contextmenu', handler);return () => kernel.events.off('contextmenu', handler);}, [kernel]);return menuItems;
}function ConfigPanel({ kernel }) {return (<div>{Array.from(kernel.ops.operations).map(([id, op]) => (<label key={id}><inputtype="checkbox"checked={kernel.config.getOperationVisibility(id)}onChange={e => kernel.config.updateOperationConfig(id, {visibleInContextMenu: e.target.checked})}/>{op.name}</label>))}</div>);
}
  • 节点表单
function PropertyPanel({ node, kernel }) {const schema = kernel.nodes.getFormSchema(node.type);return (<ConfigFormschema={schema}formData={node.data}onChange={({ formData }) => {kernel.events.emit("nodeUpdate", {id: node.id,data: formData,});}}/>);
}

使用示例

  • 自定义页面基础布局
function App() {const [kernel, setKernel] = useState(null);useEffect(() => {const kernel = new FlowKernel();// 自定义节点/插件kernel.registerNode(CustomNode);kernel.registerOperation(CopyOperation);kernel.registerOperation(PasteOperation);setKernel(kernel);}, []);return (<div className="flow-editor"><div className="sidebar"><NodePalette kernel={kernel} /><ConfigPanel kernel={kernel} /></div><div className="main"><Toolbar kernel={kernel} /><ReactFlownodes={nodes}edges={edges}nodeTypes={kernel.nodes.getComponents()}onNodeClick={handleNodeClick}/><PropertyPanel kernel={kernel} /></div></div>);
}
  • 自定义节点
const CustomNodeComponent = ({ data }) => {};
export const CustomNode = {id: "custom-node",node: {component: CustomNodeComponent,formSchema: {},defaultConfig: {},},edge: {component: CustomEdgeComponent,formSchema: {},defaultConfig: {},},
};
  • 复制/粘贴操作插件
const CopyOperation = {type: "operation",meta: {id: "copy-op",name: "复制",icon: <CopyIcon />,visibility: ["toolbar", "contextmenu"],execute: ({ selectedNodes, kernel }) => {kernel.clipboard.set(clipboardData);kernel.events.emit("copy", selectedNodes);},},activate(kernel) {kernel.hotkeys.register("ctrl+c", () => {if (kernel.selection.hasSelection) {this.meta.execute({selectedNodes: kernel.selection.selectedNodes,kernel,});}});kernel.events.on("doubleclick", ({ node }) => {this.meta.execute({ selectedNodes: [node], kernel });});},deactivate(kernel) {kernel.hotkeys.unregister("ctrl+c");},
};const PasteOperation = {type: "operation",meta: {id: "paste-op",name: "粘贴",icon: <PasteIcon />,visibility: ["toolbar", "contextmenu"],execute: ({ kernel }) => {const clipboardData = kernel.clipboard.get();if (!clipboardData) {return;}// 计算偏移量const offset = 50;const newNodes = clipboardData.nodes.map((node, index) => ({...node,id: `copied-${node.id}-${clipboardData.timestamp}-${index}`,position: {x: node.position.x + offset,y: node.position.y + offset,},}));kernel.graph.addNode(newNodes);},},activate: (kernel) => {kernel.hotkeys.register("ctrl+v", () => {this.meta.execute({ kernel });});},deactivate: (kernel) => {kernel.hotkeys.unregister("ctrl+v");},
};

undo/redo 操作

两种实现方式:记录数据和命令模式

记录数据

基础数据结构:

interface OperationRecord {meta,//操作元数据,比如操作类型、操作参数等data,//该次操作后的节点快照timestamp
}

使用两个栈来记录操作历史,一个栈 undoStack 用于存储撤销记录,一个栈 history 用于存储历史记录。(或者用一个 history 数组+一个指针也可实现)

每次操作都记录到 history 栈中:

//需要找到pointer的位置在其后插入
kernel.history.push(record);

撤销操作:

kernel.history.pop();
const record = kernel.history[currentPointer];
kernel.undoStack.push(record);
kernel.graph.set(record.data);

重做操作:

const record = kernel.undoStack.pop();
kernel.history.push(record);
kernel.graph.set(record.data);

移动到任意一步:

const record = kernel.history[step];
//省略将后面的数据从history中逆序移动到undoStack中过程
kernel.graph.set(record.data);

特点:

  1. 可实现操作历史,支持恢复到任意一步操作
  2. 牺牲了空间,数据量太大,需要考虑性能问题
命令模式:

命令模式一般包含以下角色:

  1. CommandManager:命令管理者,调用接收者对应接口处理发布者的请求。
  2. Receiver:接收者,执行命令的具体操作。
  3. Invoker:调用者,负责调用命令对象执行命令。
    在 js 中可以简化一下,只需要定义一个 CommandManager 和 Receiver 即可,Invoker 即为具体调用的操作
    使用一个 history 数组保存操作记录,使用一个指针指向当前操作
//举例:添加节点命令,作为Receiver,kernel.ops类比CommandManager
const AddNodeOperation = {...meta:{...execute: function({node,kernel}) {const newNode={...}this.node=newNode;kernel.graph.addNode(newNode);},undo:function({kernel}){kernel.graph.removeNode(this.node.id);}},activate:function({kernel}){}
}class CommandHistoryManager{constructor(){this.history=[];this.pointer=-1;}execute(command){command.execute();this.history.push(command);this.pointer++;}undo(){if(this.pointer>0){const command=this.history[this.pointer];command.undo();this.pointer--;}}
}

每次操作都记录到 history 栈中:

kernel.history.push(new CommandManager(AddNodeOperation));

撤销操作:

const command = history[pointer];
command.undo();

重做操作:

const command = history[pointer + 1];
command.execute();

特点:

  1. 不需要存储大量数据结构,可节省空间
  2. 无法恢复到任意步操作,只能一步步操作

关于数据存储

在 kernel 中接管了数据存储,当节点添加到画布之后,kernel 全托管了节点(特别节点需要数据回显的情况),所以数据也需要托管到 kernel 中,同样地,节点的表单数据也需要托管到 kernel 中,因此,用动态表单比普通表单也会更合适。

【参考】从 VS Code 看优秀插件系统的设计思路


文章转载自:

http://gVuAH6tP.qpfmh.cn
http://laXHGJlU.qpfmh.cn
http://6OCPcqRZ.qpfmh.cn
http://exsISyHX.qpfmh.cn
http://hRXV3E55.qpfmh.cn
http://Gj0IDIxI.qpfmh.cn
http://GFPs13XZ.qpfmh.cn
http://GTofiMmY.qpfmh.cn
http://oxjSilXM.qpfmh.cn
http://ql5z2x44.qpfmh.cn
http://AXpt1qVe.qpfmh.cn
http://ojh777u0.qpfmh.cn
http://jSPvx0x9.qpfmh.cn
http://mM7Em29C.qpfmh.cn
http://4QhnHdOx.qpfmh.cn
http://qtELxcZr.qpfmh.cn
http://UtgOQV8J.qpfmh.cn
http://cufHj5Xb.qpfmh.cn
http://YHMUxH0V.qpfmh.cn
http://NzgQEBAY.qpfmh.cn
http://WFrCRofU.qpfmh.cn
http://TfqfthHX.qpfmh.cn
http://GdQFneij.qpfmh.cn
http://y0GfXTAz.qpfmh.cn
http://0riPcL3z.qpfmh.cn
http://IW44TySx.qpfmh.cn
http://k1D6xZJn.qpfmh.cn
http://kLUT1qKC.qpfmh.cn
http://Mm7TJw6t.qpfmh.cn
http://xVsWukq4.qpfmh.cn
http://www.dtcms.com/wzjs/705737.html

相关文章:

  • 邯郸做网站优化深圳网站系统哪家强
  • 营销型网站设计稿淘宝怎么做基础销量什么网站好
  • 雷州网站建设地方门户网站赚钱
  • 丹东建设网站海外注册域名的网站好
  • 初期做网站西安有什么好玩的地方景点推荐
  • 群晖nas可以做网站服务器新闻 近期大事件
  • tinypng图片压缩网站网站公司的利润
  • 网站建设运营知乎网站建设项目培训
  • 软件工程师招聘信息网站备案网查询
  • 怎样做网站 app教程2345网址导航是谷歌吗
  • 合肥网站建设公网站一般都是用什么软件做的
  • 网站推广妙招企业信息查询表去哪里查
  • 模版网站利于优化快站心动小程序官网
  • 企业网站建设如何做好外链建设设计家装修效果图软件
  • 苏州网站建设排行wordpress 移动商城主题
  • wordpress建立php站点地图厦门建设银行招聘网站
  • 购物平台网站建设框架小程序编辑
  • 网站信息内容建设局通报包装印刷
  • 处方药可以做网站吗白云电子商务网站建设
  • 网站优化一般要怎么做电商怎么做的
  • 毕业设计做旅游网站建站外贸企业官网推广
  • 中山哪家做网站好有没有淄博张店做兼职工作的网站
  • 腾讯云网站搭建seo网站推广招聘
  • 丹阳网站建设如何中国建筑公司排名一览表
  • 网站手机验证码怎么做首商网官网
  • dede 企业网站模板品牌形象设计包括什么
  • 营销型网站的现状dedecms资源下载模板
  • 静态网站托管天津建设协会网站
  • 双流网站建设品牌设计主要做哪些内容
  • 企业网站建设移动天津软件开发培训机构