【问题标题】:How to create an interface? [duplicate]如何创建接口? [复制]
【发布时间】:2026-01-20 15:05:01
【问题描述】:

我想在 Javascript 中创建一个界面,有人知道怎么做吗?

在 PHP 中,我可以为多个数据库创建一个接口:

interface Database{
    function connect($dsn,$user,$pass,$option);
    function prepare($query);
    function find($table,$column,$condition);
    function save($table,$column,$condition);
}

class MySQL implements Database{
    function connect($dsn,$user,$pass,$option){ ... }
    function prepare($query){ ... }
    function find($table,$column,$condition){ ... }
    function save($table,$column,$condition){ ... }
}

class Oracle implements Database{
    function connect($dsn,$user,$pass,$option){ ... }
    function prepare($query){ ... }
    function find($table,$column,$condition){ ... }
    function save($table,$column,$condition){ ... }
}

以后,当我需要查询一个表时,我可以简单地执行:

$db = new MySQL;
$db->find('table','column','condition');

【问题讨论】:

  • 不是一个真正的答案,但如果你想在 javascript 中做这样的事情,你应该看看 Typescript。
  • Javascript 非常原始,你不能创建“接口”,你将如何在对象上调整它?
  • @arjan 所有这些答案似乎都没有给出适当对象的简单构造示例。虽然是同一个主题,但问题以及相应的答案却在截然不同的层面上。
  • @eBusiness:那是因为在鸭式打字中,如何这些对象是构造完全不相关的。它可以由对象字面量构成,由构造函数实例化,从工厂溢出,甚至是本机对象。重要的是它们的外观。
  • @Bergi 但是您仍然必须以一种或另一种方式构造对象才能达到这一点,如果 OP 不清楚该过程,则有必要提供一个示例,上述问题没有提供.

标签: javascript php oop


【解决方案1】:

我制作了一个你可以确定为接口的函数:

var MySQL = function(){
    DatabaseInterface(this);
};
MySQL.prototype.connect = function(dsn,user,pass,option){
    //
};
MySQL.prototype.prepare = function(query){
    //
};
MySQL.prototype.find = function(table,column,condition){
    //
};
MySQL.prototype.save = function(table,column,condition){
    //
};
new MySQL;

function DatabaseInterface(con){
    if(!'connect' in con || !getParamNames(con.connect) == "dsn,user,pass,option") 
        throw new Error("This method is not correctly overwritten1!");
    if(!'prepare' in con || !getParamNames(con.prepare) == "query")
        throw new Error("This method is not correctly overwritten2!");    
    if(!'find' in con || !getParamNames(con.find) == "table,column,condition")
        throw new Error("This method is not correctly overwritten3!");
    if(!'save' in con || !getParamNames(con.save) == "table,column,condition")
        throw new Error("This method is not correctly overwritten4!");
}
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function getParamNames(func) {
    var fnStr = func.toString().replace(STRIP_COMMENTS, '')
    var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(/([^\s,]+)/g)
    if(result === null)
        result = []
        return result
}

在你的 mysql 类的构造函数中,你说调用 DatabaseInterface 函数。该函数检查它是否是正确的数据库连接器。如果不是,他会抛出一个错误。这很奇怪,但它按预期工作。

但是看看电子商务和所有其他 cmets 的答案。 javascript 中没有接口,在大多数情况下您不需要它。

EXAMPLE

【讨论】:

    【解决方案2】:

    您可以简单地使用一组函数创建一个对象,然后您可以将另一个对象替换为另一个数据库的相应函数。

    dbInterface={
        search:function(searchstring){
            this.oracleDB.somethingDo(searchstring)
        }
        ,oracleDB=new Oracle("foobar")
    }
    //dbInterface is now an object with the method "search".
    

    在这种情况下,this 指的是函数附加到的对象

    一种常见的方法是使用构造函数构建这些对象,该构造函数也用作闭包,从而提供方便的局部范围:

    function MySQLinteface(initialization, parameters){
        var dbConnection=connect(parameters)
        this.search=function(searchstring){
            dbConnection.doSomething(searchstring)
        }
    }
    dbInterface=new MySQLinteface("foo", "bar")
    //dbInterface is now an object with the method "search".
    

    在这种情况下this是构造函数的返回对象,因为它是用new关键字调用的。

    在这两种情况下,关键部分是您获得了一个公开方法search 的对象。你不必正式定义一个接口,你只需要决定你希望你的接口如何,然后你可以以任何你喜欢的方式重新实现它,并且所有这些实现都是插件的替代品另一个。

    【讨论】:

      【解决方案3】:

      JavaScript 不是静态类型的,因此不能声明任何接口。您只需创建履行合同的对象(如果需要,您可以动态测试对象是否提供此类方法)。这称为duck typing - 如果一个对象具有connectpreparefindsave 方法,我们认为它是一个数据库接口。有各种辅助函数库可以简化此类测试的声明/创建。

      【讨论】: