Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 加载不同的类并执行类似的函数名_Javascript_Node.js - Fatal编程技术网

Javascript 加载不同的类并执行类似的函数名

Javascript 加载不同的类并执行类似的函数名,javascript,node.js,Javascript,Node.js,我有一个无法解决的问题。 假设我们在一个名为services的目录中有一些类。 这些类中的每一个都包含一个constructor()和send()方法。 我们可以有不同的类,例如不和谐,松弛,短信,等等。 他们的目标只是通过外部服务发送通知 我想我必须使用一个包含constructor()和send()方法的接口或抽象类,但是我如何才能将每个类实例化并以优雅的方式调用send() 我的项目结构: services/ -> discord.js -> slack.js -&

我有一个无法解决的问题。 假设我们在一个名为
services
的目录中有一些类。 这些类中的每一个都包含一个
constructor()
send()
方法。 我们可以有不同的类,例如
不和谐
松弛
短信
,等等。 他们的目标只是通过外部服务发送通知

我想我必须使用一个包含
constructor()
send()
方法的接口或抽象类,但是我如何才能将每个类实例化并以优雅的方式调用
send()

我的项目结构:

services/
  -> discord.js
  -> slack.js
  -> [...]
index.js

尊敬。

我认为您需要的是一种管理器,其中有一个
send()
函数,可以根据参数选择特定的服务。大概是这样的:

服务/index.js

import SlackService from 'slack.js';
import DiscordService from 'discord.js';

export const TYPES = {
  SLACK: 'slack',
  DISCORD: 'discord',
};

export class ServiceManager {
  services;

  constructor() {
    this.services = {
      [TYPES.DISCORD]: new DiscordService(/* discordConfig */),
      [TYPES.SLACK]: new SlackService(/* slackConfig */),
    };
  }

  send(type, data) {
    return this.services[type].send(data);
  }
}
import ServiceManager from 'services/index.js';
const serviceManager = new ServiceManager();

serviceManager.send(ServiceManager.TYPES.SLACK, { message: 'Sent to Slack' });
serviceManager.send(ServiceManager.TYPES.DISCORD, { message: 'Sent to Discord' });
const requireDir = require('require-dir');

export class ServiceManager {
  services;

  constructor() {
    const serviceObjects = requireDir('.');
    this.services = Object.values(serviceObjects).reduce(
      (services, { name, Service }) => {
        services[name] = new Service();
        return services;
      }
    )
  }

  getRegisteredServices() {
    return Object.keys(this.services);
  }

  send(name, data) {
    return this.services[name].send(data);
  }

  sendAll(data) {
    Object.values(this.services).each(service => service.send(data));
  }
}
index.js

import SlackService from 'slack.js';
import DiscordService from 'discord.js';

export const TYPES = {
  SLACK: 'slack',
  DISCORD: 'discord',
};

export class ServiceManager {
  services;

  constructor() {
    this.services = {
      [TYPES.DISCORD]: new DiscordService(/* discordConfig */),
      [TYPES.SLACK]: new SlackService(/* slackConfig */),
    };
  }

  send(type, data) {
    return this.services[type].send(data);
  }
}
import ServiceManager from 'services/index.js';
const serviceManager = new ServiceManager();

serviceManager.send(ServiceManager.TYPES.SLACK, { message: 'Sent to Slack' });
serviceManager.send(ServiceManager.TYPES.DISCORD, { message: 'Sent to Discord' });
const requireDir = require('require-dir');

export class ServiceManager {
  services;

  constructor() {
    const serviceObjects = requireDir('.');
    this.services = Object.values(serviceObjects).reduce(
      (services, { name, Service }) => {
        services[name] = new Service();
        return services;
      }
    )
  }

  getRegisteredServices() {
    return Object.keys(this.services);
  }

  send(name, data) {
    return this.services[name].send(data);
  }

  sendAll(data) {
    Object.values(this.services).each(service => service.send(data));
  }
}

从文件动态加载服务 您可以使用
requiredir
从目录导入所有文件,然后映射这些文件以创建每个服务。必须以定义的语法编写各个服务文件,以便管理者使用它们。大概是这样的:

服务/slack.js(作为所有服务文件的示例):

服务/index.js

import SlackService from 'slack.js';
import DiscordService from 'discord.js';

export const TYPES = {
  SLACK: 'slack',
  DISCORD: 'discord',
};

export class ServiceManager {
  services;

  constructor() {
    this.services = {
      [TYPES.DISCORD]: new DiscordService(/* discordConfig */),
      [TYPES.SLACK]: new SlackService(/* slackConfig */),
    };
  }

  send(type, data) {
    return this.services[type].send(data);
  }
}
import ServiceManager from 'services/index.js';
const serviceManager = new ServiceManager();

serviceManager.send(ServiceManager.TYPES.SLACK, { message: 'Sent to Slack' });
serviceManager.send(ServiceManager.TYPES.DISCORD, { message: 'Sent to Discord' });
const requireDir = require('require-dir');

export class ServiceManager {
  services;

  constructor() {
    const serviceObjects = requireDir('.');
    this.services = Object.values(serviceObjects).reduce(
      (services, { name, Service }) => {
        services[name] = new Service();
        return services;
      }
    )
  }

  getRegisteredServices() {
    return Object.keys(this.services);
  }

  send(name, data) {
    return this.services[name].send(data);
  }

  sendAll(data) {
    Object.values(this.services).each(service => service.send(data));
  }
}
index.js(基本保持不变)


javascript中没有接口或抽象类。实例化某些类的方法有数千种,我也遇到了同样的问题,所以我创建了一个接口解决方案来解决这个问题。如果你愿意,你可以安装它。问题是什么还不清楚
require
一个类,实例化它并调用
send
@estus我需要多态性或类似多态性的东西。@Oyabi Javascript类型化了。没有接口的概念。只要调用这个方法,如果它存在,它就会工作。啊,我想这或多或少是我想要的。非常感谢你。但是,如果我添加一个新类(例如SMS),我必须在3个文件中添加代码:services/SMS.js、services/index.js和index.js。从软件架构的角度来看,这听起来正确吗?我们不能实例化services/index.js中的所有类并在index.js中通过ServiceManager对象进行循环吗?因此index.js代码不会随着每次提交而改变。我只是用一个稍微不同的ServiceManager扩展了我的答案,它会自动加载所有可用的服务。这样,您只需添加一个文件
service/sms.js
,经理就会识别它。您仍然需要将代码添加到
index.js
。该文件只是作为应用程序代码中希望使用特定服务的任何地方的示例。但是,两种解决方案都可以添加
sendAll
功能。非常感谢!我将对此进行研究,并在我的应用程序中实现您的解决方案。祝你度过愉快的一天,再次感谢你的时间和经验。没问题。很高兴我能帮忙。