ES6クラスを使用したシングルトンパターンを使用するパターンがあり、ファイルの下部でクラスをインスタンス化してインスタンスをエクスポートするのではなく、なぜそれらを使用するのか疑問に思っています。これを行うことには何らかの負の欠点がありますか?例えば:
ES6エクスポートインスタンス:
import Constants from '../constants';
class _API {
constructor() {
this.url = Constants.API_URL;
}
getCities() {
return fetch(this.url, { method: 'get' })
.then(response => response.json());
}
}
const API = new _API();
export default API;
使用法:
import API from './services/api-service'
次のシングルトンパターンを使用することとの違いは何ですか?どちらか一方を使用する理由はありますか?実際、私が最初に挙げた例に気づいていない問題があるかどうかを知りたいと思っています。
シングルトンパターン:
import Constants from '../constants';
let instance = null;
class API {
constructor() {
if(!instance){
instance = this;
}
this.url = Constants.API_URL;
return instance;
}
getCities() {
return fetch(this.url, { method: 'get' })
.then(response => response.json());
}
}
export default API;
使用法:
import API from './services/api-service';
let api = new API()
違いは、物事をテストするかどうかです。
api.spec.js
テストファイルがあるとします。また、APIには、定数のように1つの依存関係があります。
具体的には、両方のバージョンのコンストラクターは、Constants
インポートという1つのパラメーターを取ります。
したがって、コンストラクタは次のようになります。
class API {
constructor(constants) {
this.API_URL = constants.API_URL;
}
...
}
// single-instance method first
import API from './api';
describe('Single Instance', () => {
it('should take Constants as parameter', () => {
const mockConstants = {
API_URL: "fake_url"
}
const api = new API(mockConstants); // all good, you provided mock here.
});
});
インスタンスをエクスポートすると、モックはありません。
import API from './api';
describe('Singleton', () => {
it('should let us mock the constants somehow', () => {
const mockConstants = {
API_URL: "fake_url"
}
// erm... now what?
});
});
インスタンス化されたオブジェクトをエクスポートすると、その動作を(簡単かつ正気に)変更できません。
私はどちらもお勧めしません。これは完全に複雑です。オブジェクトが1つだけ必要な場合は、 class
構文を使用しないでください !ただ行く
import Constants from '../constants';
export default {
url: Constants.API_URL,
getCities() {
return fetch(this.url, { method: 'get' }).then(response => response.json());
}
};
import API from './services/api-service'
または さらに簡単
import Constants from '../constants';
export const url = Constants.API_URL;
export function getCities() {
return fetch(url, { method: 'get' }).then(response => response.json());
}
import * as API from './services/api-service'
シングルトンパターンを使用するもう1つの理由は、一部のフレームワーク(Polymer 1.0
など)でexport
構文を使用できないことです。
だからこそ、2番目のオプション(シングルトンパターン)の方が便利です。
それが役に立てば幸い。
両方とも異なる方法です。以下のようなクラスをエクスポートします
const APIobj = new _API();
export default APIobj; //shortcut=> export new _API()
そして、以下のように複数のファイルにインポートすると、同じインスタンスとシングルトンパターンの作成方法が指定されます。
import APIobj from './services/api-service'
クラスを直接エクスポートする他の方法は、インポートするファイルのようにシングルトンではありませんが、クラスを更新する必要があります。これにより、エクスポートクラスごとに個別のインスタンスが作成されます。
export default API;
クラスのインポートと更新
import API from './services/api-service';
let api = new API()