Implémentation du modèle d'usine – mise en cache des données

Pendant le développement, une fonction de mise en cache des données est nécessaire. Par exemple, un formulaire doit remplir le nom d'utilisateur, les informations de la carte d'identité, l'âge, etc.

Première étape:

Mise en cache directement avec sp

Problème : aucune conception, beaucoup de code écrit, aucune extension

Note : Le principe de SharedPreferences est également d'exploiter les fichiers. Enregistrez-les au format XML. Faites attention à la soumission du commit.

Deuxième étape :

Écrivez-le dans une classe d'outils PreferencesUtils, puis initialisez-le dans Application

 PreferencesUtils.getInstance().init(this);
  • Approche singleton de l'objet PreferencesUtils
  • Utiliser des appels chaînés pour définir des données spécifiques
public class PreferencesUtils {
    private volatile static PreferencesUtils mInstance;
    private SharedPreferences mPreferences;
    private SharedPreferences.Editor mEditor;

    private PreferencesUtils(){

    }

    public void init(Context context){
        mPreferences = context.getApplicationContext().getSharedPreferences("cache",Context.MODE_PRIVATE);
        mEditor = mPreferences.edit();
    }

    public static PreferencesUtils getInstance(){
        if(mInstance == null){
            synchronized (PreferencesUtils.class){
                if(mInstance == null){
                    mInstance = new PreferencesUtils();
                }
            }
        }
        return mInstance;
    }

    public PreferencesUtils saveString(String key,String value){
        mEditor.putString(key,value);
        return this;
    }

    public void commit(){
        mEditor.commit();
    }

    public String getString(String key){
        return mPreferences.getString(key,"");
    }
}

Problème : Il est impossible de vider une partie du cache et il est impossible de combiner le cache mémoire avec le cache disque ou le cache de base de données.

Troisième étape :

Utiliser un modèle d'usine simple

1. Définir la spécification IOHandler pour le stockage des données

public interface IOHandler {
    void save(String key,String value);

    String getString(String key);
}

2. Définissez des classes de cache spécifiques, telles que : cache mémoire, cache SP

// 内存缓存
public class MemoryIOHandler implements IOHandler {
    // 存在运行内存里面 内部原理:LinkedHashMap
    private static LruCache<String, Object> mCache = new LruCache<>(10 * 1024 * 1024); 

    @Override
    public void save(String key, String value) {
        mCache.put(key, value);
    }

    @Override
    public String getString(String key) {
        return (String) mCache.get(key);
    }
}

// SP缓存
public class SpIOHandler implements IOHandler{
    @Override
    public void save(String key, String value) {
        PreferencesUtils.getInstance().saveString(key,value);
    }

    @Override
    public String getString(String key) {
        return PreferencesUtils.getInstance().getString(key);

    }
}

3. Définir la classe d'usine

public class IOHandlerFactory {
    public enum IOType{
        MEMORY,PREFERENCES
    }
    public static IOHandler createIOHandler(IOType ioType){
        switch (ioType){
            case MEMORY:
                return new MemoryIOHandler();
            case PREFERENCES:
                return new SpIOHandler();
            default:
                return null;
        }
    }
}

Question : Si vous devez ajouter une nouvelle méthode de mise en cache, vous devez ajouter un type et modifier la classe d'usine.

Quatrième étape :

En utilisant le modèle de méthode d'usine, chaque usine correspond à un produit et l'usine est appelée en externe à l'aide de produits spécifiques.

Un IOFactory correspond à un IOHandler

1.IOHandler reste inchangé

2. Créez une interface d'usine

public interface IOFactory {
     IOHandler createIOHandler();
}

3. Créez une usine spécifique

Ne produisez qu'un seul produit. Si vous devez ajouter un nouveau type, il vous suffit de créer un produit et d'ajouter la méthode du produit.

public class MemoryIOFactory implements IOFactory{
    @Override
    public IOHandler createIOHandler() {
        return new MemoryIOHandler();
    }
}

public class SpIOFactory implements IOFactory{
    @Override
    public IOHandler createIOHandler() {
        return new PreferencesIOHandler();
    }
}

4. Appels externes

        IOFactory ioFactory = new MemoryIOFactory();
        IOHandler ioHandler = ioFactory.createIOHandler();

Problème : avec l'expansion des fonctions, les classes d'usine continuent d'augmenter et la logique de base est la même, ce qui entraîne un code redondant.

Cinquième étape :

modèle d'usine abstrait

1.IOHandler reste inchangé

2. Définissez IOFactory et utilisez une classe générique

public interface IOFactory {
    IOHandler createIOHandler(Class<? extends IOHandler> ioHandlerClass);
}

3. Utilisez un singleton pour créer une fabrique abstraite, IOHandlerFactory

public class IOHandlerFactory implements IOFactory {
    private static volatile  IOHandlerFactory mInstance;
    private IOHandler mMemoryIOHandler,mSpIOHandler;

    private IOHandlerFactory(){

    }

    public static IOHandlerFactory getInstance(){
        if(mInstance == null){
            synchronized (IOHandlerFactory.class){
                if(mInstance == null){
                    mInstance = new IOHandlerFactory();
                }
            }
        }
        return mInstance;
    }

    public IOHandler createIOHandler(Class<? extends IOHandler> ioHandlerClass){
        try {
            return ioHandlerClass.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new PreferencesIOHandler();
    }

    public IOHandler getMemoryIOHandler(){
        if(mMemoryIOHandler == null){
            mMemoryIOHandler = createIOHandler(MemoryIOHandler.class);
        }
        return mMemoryIOHandler;
    }

    public IOHandler getDiskIOHandler(){
        return createIOHandler(DiskIOHandler.class);
    }

    public IOHandler getSpIOHandler(){
        if(mPreferencesIOHandler == null){
            mSpIOHandler = createIOHandler(SpIOHandler.class);
        }
        return mPreferencesIOHandler;
    }

    public IOHandler getDefaultIOHandler(){
        return getMemoryIOHandler();
    }
}

4. Appels externes

IOHandler ioHandler =  IOHandlerFactory.getInstance().getDefaultIOHandler();

scènes à utiliser :

Il y a des points communs, mais il peut y avoir de la diversité plus tard : il est nécessaire de cacher les détails complexes de la création et d'encapsuler l'instanciation et la création d'objets.

Par exemple:

        Utilisation d'une base de données, d'une bibliothèque de chargement d'images, d'une bibliothèque de chargement réseau, etc. S'il existe un nouveau framework ultérieurement et que vous souhaitez le remplacer, vous pouvez utiliser le mode usine pour le créer et remplacer les fonctions d'origine avec des modifications minimes.

Guess you like

Origin blog.csdn.net/weixin_42277946/article/details/131157992