首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在代码中实现依赖注入和单责任原则

如何在代码中实现依赖注入和单责任原则
EN

Stack Overflow用户
提问于 2019-05-23 13:38:21
回答 1查看 284关注 0票数 1

我正在创建一个新的简单应用程序来标记和删除给定文本中的停止词。为此,我创建了以下文件:

代码语言:javascript
复制
// Stopword.js
class StopWord {
    constructor (stopWords) {
        this.stopWords = stopWords
    }
    remove (value) {
        // do whatever we need to remove this.stopWords from the passed value and return it
    }

}
代码语言:javascript
复制
// PreProcess.js
const StopWord = require('./StopWord')
class PreProcess {
    setValue (value) {
        this.value = value
        return this
    }
    removeStopWords (stopWords) {
        const stopWord = new StopWord(stopWords)
        return stopWord.remove(this.value)
    }

}
代码语言:javascript
复制
// Indexed.js
class Indexer {
    setValue (value) {
        this.value = value
        return this
    }
    setStopWords (stopWords) {
        this.stopWords = stopWords
        return this
    }
    index () {
        return this.preprocess
            .setValue(this.value)
            .removeStopWords(stopWords)
    }

}
代码语言:javascript
复制
// main.js
const indexer = new Indexer()
const result = indexer
    .setValue('a sample text ')
    .setStopWords(['a', 'an'])
    .index()

console.log(result)

假设在某些情况下,我们希望动态地从数据库加载停止词(不同用户的停止词不同)。出现的第一个问题是,我们需要在哪个类中从数据库加载停止单词?显然,类PreProcess是使用依赖注入注入索引的。类StopWord也可以使用DI注入,但我想知道这是否足够好。第二个问题是,应该将哪些类注入哪一类?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-23 18:24:01

不要试图根据需要使事情变得更复杂:-)从您目前的名称来看,我不知道如何使用该功能。什么是索引器?什么是预处理器?那些东西可能是任何东西。因此,让它保持简单,从域的角度直接到重点(我将在TypeScript中给出示例,这样您就可以看到在哪里使用了哪些类型):

首先,我们将定义停止词域服务(业务域):

代码语言:javascript
复制
/** we'll use this to provide stop words as array of strings */
class StopWords {
    public stopWords: string[] = [];
    constructor(words?: string[]) { this.stopWords = words }
}
/** single responsibility of this class: actually remove the stopwords */
class StopWordsRemovalService {
    /** inject stopwords through constructor */
    constructor(stopWords: StopWords) {}
    /** here we do the real removal work */
    public removeAllStopWordsFrom(text: string): string { return ''; }
}

现在,我们可以从任何位置(基础设施方面的更多信息)提供停止词:

代码语言:javascript
复制
/** TypeScript provids interfaces, which you don't have in plain JS. It merely 
 * defines the class method signatures, which is quite useful in software design */
interface StopWordsProvider {
    getStopWords(): StopWords;
}
class DefaultStopWordsProvider implements StopWordsProvider {
    getStopWords(): StopWords {
        return new StopWords(['a', 'an']);
    }
}
class DbStopWordsProvider implements StopWordsProvider {
    getStopWords(): StopWords {
        return db.query("SELECT stopWords FROM ...");
    }
}

最后,我们将连接在一起:

代码语言:javascript
复制
const swremoval: StopWordsRemovalService  = new StopWordsRemovalService(new DefaultStopWordsProvider().getStopWords());
swremoval.removeAllStopWordsFrom('a sample text');

要将事情连接在一起,现在可以使用依赖项注入框架(如InversifyJS )。

更新:我们需要通过用户ID返回不同的停止词。

我在这里想到的第一个问题是,用户ID对业务有多重要?如果总是需要用户ID来确定停止词,则用户ID是我们域的一个组成部分!如果有时需要用户ID来确定停止词,则它可能不是我们域的一个组成部分。让我们来研究这两种情况:

检索停止词总是需要用户ID。

如果用户ID对域很重要,并且总是需要确定停止词,那么让我们将其作为契约的一部分:

代码语言:javascript
复制
/** TypeScript provids interfaces, which you don't have in plain JS. It merely 
 * defines the class method signatures, which is quite useful in software design */
interface StopWordsProvider {
    /** Returns all the stop words for the given user */
    getStopWords(userID: number): StopWords;
}

现在,实现此接口的所有类都需要尊重用户ID。

有时需要用户ID来检索停止词。

如果某些查找只需要用户ID,我们将不会更改停止词契约(即界面)!相反,我们将提供一个执行查找的UserSpecificStopWordsProvider。要配置用户ID,我们将使用工厂模式:

代码语言:javascript
复制
/** The user-specific stopwords provider is configured through
 *  constructor-based injection */
class UserSpecificStopWordsProvider implements StopWordsProvider {
    constructor(private userId: number) {}
    getStopWords(): StopWords {
        return db.query("SELECT * FROM sw WHERE userId = :userId", this.userId);
    }
}

/** To simplify the usage, we'll provide a factory to do this. */
class UserSpecificStopWordsProviderFactory {
    factoryProvider(userId: number): StopWordsProvider {
        // potentially inject more dependencies here
        return new UserSpecificStopWordsProvider(userId);
    }
}

/** We can then use it as follows: */
const factory = new UserSpecificStopWordsProviderFactory();
factory.factoryProvider(5).getStopWords();
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56276532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档