English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Androidプログラミングデザインパターンのプロトタイプパターンの詳細な例解

1. プロジェクト使用中に露出したいくつかの問題

「aaa」= 'これはサンプル文字列です' などの原生语法を使用してどこでも直接LocalStorageにアクセスするようにしていますが、これによりコードの緊密度が高くなります。もし実装方法を変更したり、ストレージのサイズを制御する必要がある場合、多くのコードを修正する必要があります

プロジェクトが大きい場合、キーの名前が重複する可能性があり、これによりグローバルな汚染が発生します

LocalStorageの使用が規範化されていないため、ストレージ空間の無駄と不足が発生しました

2. 解決策

storageの使用方法をエンキャップし、統一して処理

storageのキー値の命名規則を規範化
storageの使用規則を規範化

2.1. 一貫したメソッドのエンキャップ

メソッドにエンキャップすることで、コードの緊密度を低減し、実装方法を切り替えやすく、ストレージの容量を制御できます

実装の変更は、異なるパラメータを設定することで実現できます

図のようにプロジェクト構造を編集します

コード実装

/*
 * storage.js
 */
/*
 * @Author: 石国庆
 * @Desc: ローカルデータストレージメソッドのエンキャップ
 * @Date: 2017.11.14
 * @Ref:
 *  https://github.com/WQTeam/web-storage-cache
 *  https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage
 * @Explain:オブジェクトをnewしないように、何度も書かなくてはなりません
 * @Example:
 *
 * 1LocalStorageの使用
 * import storage from '@/utils/storage.js'
 * storage.setItem('shiguoqing0',[1,2,3,4,5,6])
 * storage.setItem('shiguoqing1},{userId:'dfdf',token:11232323)
 * storage.setItem('shiguoqing2','dfdfdf')
 * console.log(storage.getItem('shiguoqing0'))
 * console.log(storage.getItem('shiguoqing1))
 * console.log(storage.getItem('shiguoqing2))
 * storage.removeItem('shiguoqing2')
 *
 *
 * 2、SessionStorageの使用
 * storage.setItem('shiguoqing0',[1,2,3,4,5,6],{type:'session'})
 *
 * */
// TODO:他のメソッドの実現
// TODO:タイムアウト時間の設定
/*
 * メソッドの実現
 * */
import local from './storage/localstorage.js'
import session from './storage/session.js'
import cookies from './storage/cookies.js'
import json from './storage/json.js'
/*
* 関数本体
* */
let storage= {
 config:{
  type:'local',// local,session,cookies,json
  expires:new Date().getTime() + 100 * 24 * 60 * 60 * 1000
 },
 getStorage(options){
  let config={}
  if(options){
   config=Object.assign({},this.config,options)
  }else{
   config=this.config
  }
  return this.createStorage(config.type)
 },
 createStorage(name){
  switch(name){
   case 'local':return local;break
   case 'session':return session;break
   case 'cookies':return cookies;break
   case 'json':return json;break
  }
 },
 getItem(key,options){
  let store=this.getStorage(options)
  return store.getItem(key)
 },
 setItem(key, value,options){
  let store=this.getStorage(options)
  store.setItem(key,value)
 },
 removeItem(key,options){
  let store=this.getStorage(options)
  store.removeItem(key)
 },
 getAll(){},
 clear(options){
  let store=this.getStorage(options)
  store.clear()
 },
 key(n){},
 lenght(){},
 has(key){},
 forEach(cb){},
 deleteAllExpires(){},
 // 最大存储空间の取得:LocalStorageおよびSessionStorageのみこのメソッドを使用できます
 getMaxSpace(options){
  let store=this.getStorage(options)
  store.getMaxSpace()
 },
 // 使用されている空間を取得:LocalStorageとSessionStorageのみこのメソッドを使用できます
 getUsedSpace(options){
  let store=this.getStorage(options)
  store.getUsedSpace()
 }
}
export default storage
// https://segmentfault.com/a/1190000002458488
// 5、localStorageに保存されたキーをループ
//  .length データの合計数、例:localStorage.length
//  .key(index) でキーを取得、例:var key=localStorage.key(index);
// 备注:localStorageに保存されたデータは、ブラウザ間で共有できません。それぞれのブラウザはそれぞれのブラウザのデータを読み取ることができます、保存スペース5M。
// タイムアウト設定
// function(st, key, value, expires) {
//  if (st == 'l') {
//   st = window.localStorage;
//   expires = expires || 60;
//  } else {
//   st = window.sessionStorage;
//   expires = expires || 5;
//  }
//  if (typeof value != 'undefined') {
//   try {
//    return st.setItem(key, JSON.stringify({
//     data: value,
//     expires: new Date().getTime() + expires * 1000 * 60
//    });
//   }
//  } else {
//   var result = JSON.parse(st.getItem(key) || '{}');
//   if (result && new Date().getTime() < result.expires) {
//    return result.data;
//   } else {
//    st.removeItem(key);
//    return null;
//   }
//  }
// }
/*
 * localstorage.js
 * localstorageの実装
 */
// これは少し奇妙です、ファイル名がlocal.jsでjsファイルとして解析できない
export default {
 getItem(key){
  let item = localStorage.getItem(key)
  // これは文字列かオブジェクトかを判断する必要があります
  let result = /^[{\[].*[}\]]$/g.test(item)
  if (result) {
   return JSON.parse(item)
  } else {
   return item
  }
 },
 setItem(key, value){
  // これは文字列かオブジェクトかを判断する必要があります
  if (typeof value == "string") {
   localStorage.setItem(key, value)
  } else {
   let item = JSON.stringify(value)
   localStorage.setItem(key, item)
  }
 },
 removeItem(key){
  localStorage.removeItem(key)
 },
 getAll(){},
 clear(){
  localStorage.clear()
 },
 key(n){},
 forEach(cb){},
 has(key){},
 deleteAllExpires(){},
 // localstorageの最大ストレージ容量を取得
 getMaxSpace(){
  if (!window.localStorage) {
   console.log('現在のブラウザはlocalStorageをサポートしていません!')
  }
  var test = '0'123456789'''
  var add = function (num) {
   num += num
   if (num.length == 10240) {
    test = num
    return
   }
   add(num)
  }
  add(test)
  var sum = test
  var show = setInterval(function () {
   sum += test
   try {
    window.localStorage.removeItem('test')
    window.localStorage.setItem('test', sum)
    console.log(sum.length / 1024 + 'KB')
   }
    console.log(sum.length / 1024 + 'KBが最大制限を超えています')
    clearInterval(show)
   }
  }, 0.1)
 },
 // 使用されているlocalStorageの容量を取得します
 getUsedSpace(){
  if (!window.localStorage) {
   console.log('ブラウザはlocalStorageをサポートしていません')
  }
  var size = 0
  for (item in window.localStorage) {
   if (window.localStorage.hasOwnProperty(item)) {
    size += window.localStorage.getItem(item).length
   }
  }
  console.log('現在のlocalStorageの使用容量は' +  / 1024).toFixed(2) + 'KB')
 }
}
/*
 * session.js
 * sessionstorageの実装
 */
export default {
 getItem(key){
  let item = sessionStorage.getItem(key)
  // これは文字列かオブジェクトかを判断する必要があります
  let result = /^[{\[].*[}\]]$/g.test(item)
  if (result) {
   return JSON.parse(item)
  } else {
   return item
  }
 },
 setItem(key, value){
  // これは文字列かオブジェクトかを判断する必要があります
  if (typeof value == "string") {
   sessionStorage.setItem(key, value)
  } else {
   let item = JSON.stringify(value)
   sessionStorage.setItem(key, item)
  }
 },
 removeItem(key){
  sessionStorage.removeItem(key)
 },
 getAll(){},
 clear(){
  sessionStorage.clear()
 },
 key(n){},
 forEach(cb){},
 has(key){},
 deleteAllExpires(){},
 // localstorageの最大ストレージ容量を取得
 getMaxSpace(){
  if (!window.sessionStorage) {
   console.log('現在のブラウザはsessionStorageをサポートしていません!')
  }
  var test = '0'123456789'''
  var add = function (num) {
   num += num
   if (num.length == 10240) {
    test = num
    return
   }
   add(num)
  }
  add(test)
  var sum = test
  var show = setInterval(function () {
   sum += test
   try {
    window.sessionStorage.removeItem('test')
    window.sessionStorage.setItem('test', sum)
    console.log(sum.length / 1024 + 'KB')
   }
    console.log(sum.length / 1024 + 'KBが最大制限を超えています')
    clearInterval(show)
   }
  }, 0.1)
 },
 // 使用されているlocalStorageの容量を取得します
 getUsedSpace(){
  if (!window.sessionStorage) {
   console.log('ブラウザはsessionStorageをサポートしていません')
  }
  var size = 0
  for (item in window.sessionStorage) {
   if (window.sessionStorage.hasOwnProperty(item)) {
    size +
   }
  }
  console.log('現在のsessionStorage使用容量は' +  / 1024).toFixed(2) + 'KB')
 }
}
/*
 * cookies.js
 * cookiesの実装は、これからの人生で実現する時間もないでしょう。
 */
export default {
 getItem(key){},
 setItem(key, value){},
 removeItem(key){},
 getAll(){},
 clear(){},
 key(n){},
 forEach(cb){},
 has(key){},
 deleteAllExpires(){}
}
/*
 * json.js
 * jsonの実装は、これからの人生で実現する時間もないでしょう。
 */
export default {
 getItem(key){},
 setItem(key, value){},
 removeItem(key){},
 getAll(){},
 clear(){},
 key(n){},
 forEach(cb){},
 has(key){},
 deleteAllExpires(){}
}

2.2名前空間の使用を規範化してください。

キー値の汚染を防ぐために、名前空間を適切に使用することができます。

名前空間を定義できますが、多くのデータを同一のオブジェクトに格納することは避けましょう。その場合、後続の操作量が大きくなります。

例えば、グローバルなものはglobalの下に配置する

例えば、各機能システムにシステム接頭辞を追加する

システムのネームスペースの規範は事前に設計する必要があります。さもなければ、実際の開発中に多くの人々が規則に従わないことがあります

README.mdドキュメントにグローバルに使用されるものを反映させる必要があります

* localStorage['SGQ.global.userAuthor']:ログインするユーザーの情報はここにあります、メニュー、組織、グループ
* localStorage['SGQ.global.systemName']:ログインするシステムの名前
* localStorage['SGQ.vuex.state']:vuexのstateの保存場所、ここにはすべてのものがあります
* localStorage['SGQ.wms.warehouse']:wmsが必要とする倉庫の情報
+ localStorage['SGQ.wms.warehouse'].permissionId
+ localStorage['SGQ.wms.warehouse'].dataResource
* localStorage['SGQ.tms.org']:tmsが必要とするネットワークの情報
+ localStorage['SGQ.tms.org'].permissionId
+ localStorage['SGQ.tms.org'].orgName

2.3. storageの使用規則

2.3.1. 問題の原因

この問題は、私たちが権限ログインを行うため、ログイン中に常にストレージ空間が不足している問題が報告され、原因を調べると、バックエンドがすべての管理権限者の数千件のデータを返していることが判明しました。これにより、十分ではありませんでした。その後、バックエンドのAPIの返却データ内容を修正することで、この問題を解決しました。

しかし、今回の件は私たちにいくつかの考えを与えていますか?

localStorageとsessionstorageのストレージ容量は、異なるブラウザ間で基本的に同じです5M

localStorageとsessionstorageのストレージはドメインに従って保存されます

boss.hivescm.comの下のlocalStorageのストレージも5M

b2b.hivescm.comの下のlocalStorageのストレージも5M

今回の問題が解決したとしても、ドメイン下でlocalStorageとsessionstorageを最大限に活用するための計画を立てておくべきです10Mスペース

2.3.2. storageの使用方法

グローバルに使用されるもの、共有されるもの、永続的に保存されるものはlocalStorageに保存されます

使用完了のものは、必要がない場合はすぐに削除してください

データ量が大きい場合は、ローカルに保存しないで、動的に取得することをお勧めします

より大きなストレージ量を持つIndexeddbを使用できますが、互換性問題があります

ストレージに保存するための実装案で、保存するデータに文字数制限を設けることができます

sessionstorageとlocalStorageを十分に合理的に利用するH5特性

例えば:リストデータはvuexに保存されていますが、実際にはlocalstorageにも保存されています

例えば:フォームのバリデーションデータの一部はsessionstorageに保存されています

3. その他

3.1. 拡張

これにより、イベントの処理に類推できます。使われていないイベントは、Vueコンポーネントを退出する際に即座にクリーンアップする必要があります

例えば:this.bus.$on('aa')を使う場合はthis.bus.$off('aa')でイベントをアンラップします

3.2. 文字の長さを取得

var len = 0
for (var i = 0; i < val.length; i++) {
 if (val[i].match(/[^\x00-\xff]/ig) != null) //全角
  len += 2 //全角文字の場合、2バイトを占めます。MySQLの特定のフィールドがtextの場合、UTFエンコードとして設定されているとします。-8それでは、1つの中国語文字は占める3バイト、GBKは2バイトです
 else
  len += 1 //半角文字は1バイトを占めます
}
return len

これで、VueでlocalStorageとsessionstorageの使用法についてのすべての内容がまとめられました。ナイアラガイドのサポートをありがとうございます。

声明:この記事の内容はインターネットから収集され、著作権者に帰属します。インターネットユーザーによって自発的に提供されたコンテンツであり、このサイトは所有権を持ちません。人工編集は行われていません。また、関連する法的責任を負いません。著作権侵害を疑う内容がある場合は、メールを notice#w までお送りください。3codebox.com(メールを送信する際には、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がついたら、このサイトは即座に侵害疑いのコンテンツを削除します。)

Elasticsearchチュートリアル