¿Cómo implementar el patrón Comando para guardar y leer archivos en Android?
En este ejercicio, exploramos cómo implementar un patrón Comando en Android para guardar y leer archivos eficientemente. Este enfoque ayuda a encapsular peticiones en objetos y abre la puerta a funcionalidades como el deshacer y rehacer de acciones. Aquí aprenderás cómo desarrollar comandos para crear un sistema que interactúe eficazmente con el sistema de archivos de un dispositivo Android.
¿Cómo crear un comando para guardar archivos?
Al crear un comando para guardar archivos, comenzamos implementando una interfaz que proporciona el marco para desarrollar acciones concretas. El proceso implica varios pasos, como se detalla a continuación:
Implementación de la interfaz: Comienza creando una clase SaveCommand que implementa la interfaz Command.
Definición del método de ejecución: Implementa el método execute necesario. Aquí escribimos el contenido en un archivo de la siguiente manera:
OutputStringWriter outputStringWriter =newOutputStringWriter(fileName, context);// Suponemos que 'args' es variable con los argumentos que se desea escribiroutputStringWriter.write(args.toString());
Manejo de excepciones: Utiliza un bloque try-catch para manejar las posibles IOException que podrían surgir cuando el sistema de archivos no es accesible.
try{ outputStringWriter.close();}catch(IOException e){// Manejo de la excepciónSystem.out.println("Error al guardar el archivo: "+ e.getMessage());}
¿Cómo desarrollar un comando para leer archivos?
El comando para leer archivos es un complemento vital para el comando de guardar. Siguiendo un enfoque similar, procedemos con:
Implementación de la interfaz: Crea la clase ReadCommand implementando la interfaz Command.
Definición del método de ejecución: Aquí se lee el contenido de un archivo y se almacena en una cadena para mostrarse posteriormente.
StringBuilder fileContent =newStringBuilder();try(BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(context.openFileInput(fileName)))){String line;while((line = bufferedReader.readLine())!=null){ fileContent.append(line).append("\n");}}catch(IOException e){// Manejo de la excepciónSystem.out.println("Error al leer el archivo: "+ e.getMessage());}
¿Cómo integrar los comandos en una aplicación Android?
Para integrar los comandos, sigue estos pasos:
Crear un CommandManager: Permite agregar o solicitar comandos dados un nombre.
CommandManager commandManager =newCommandManager();commandManager.putCommand("save",newSaveCommand());// Agrega otros comandos siguiendo el mismo patrón
Invocar comandos: Utiliza el CommandManager para ejecutar los comandos creados.
// Para guardar un archivocommandManager.getCommand("save").execute(context,"exampleFile.txt","Hola Mundo","Platzi es genial");// Para leer un archivocommandManager.getCommand("read").execute(context,"exampleFile.txt");
Con estos pasos, has configurado un patrón Comando que enriquece las aplicaciones Android al manejar eficazmente operaciones de E/S de archivos. El diseño modular permite expandir, reutilizar y mantener el código más fácilmente. ¡Continúa perfeccionando tus habilidades y explora lo que puedes lograr con patrones de diseño en Android!
++Consejo:++ Mantén tu código con los espacios necesarios para que sea legible de manera sencilla 😉
Gracias por recordarmelo!
Gracias!
Con el segundo getCommand vuelve a traer el "SaveCommand", creería que debe ser el "ReadCommand". En todo caso me corrigen si estoy mal.
Debe ser ReadCommand
Good find, si es ReadCommand
Seria una buena practica hacer al CommandManager un Singleton?
Recuerda que puedes combinar varios patrones de diseño si es que lo necesitas.
Nunca he usado command en mis proyectos, aún no se si lo vaya a empezar a implementar.
Seguramente si lo vas a usar, es un patrón muy común. Es muy probable que ya lo hayas usado sin darte cuenta.
package com.cristianvillamil.platziwallet.ui.commandsimport android.content.Contextimport android.util.Logimport java.io.BufferedReaderimport java.io.InputStreamReaderclassReadCommand:FileCommand{ override fun execute(context:Context,fileName:String, vararg arguments:String){//escribir en la consola lo que vamos a leer de los archivos//vamos a hacerlo por medio de un string.var fileString =""//abrir conexion con el sistema de archivos para lectura//abrir un archivo val inputStream = context.openFileInput(fileName)//vamos a ir haciendole append a cada uno de los strings que vamos leyendo//de nuestro archivo val stringBuilder =StringBuilder()//leera el archivo val inputStreamReader =InputStreamReader(inputStream)//permitir leer linea por linea al archivo val bufferedReader =BufferedReader(inputStreamReader)//por cada linea vamos a agregar un salto de linea con \n (backslash ALT +92)//despues del salto de linea hacemos append de la linea (it viene for each line) bufferedReader.forEachLine{ stringBuilder.append("\n").append(it)}//tenemos hasta este punto un stringBuilder//tenemos que pasarlo a string fileString = stringBuilder.toString()//escribir en consolaLog.e("ReadedFile", fileString)}}
Vamos a crear dos comandos, uno para leer y otro para escribir
SaveCommand:
package com.cristianvillamil.platziwallet.ui.commands
import android.content.Context
import android.util.Log
import java.io.IOException
import java.io.OutputStreamWriter
import kotlin.math.log
class SaveCommand : FileCommand {overridefunexecute(context: Context, fileName: String,vararg arguments: String){try{val outputStreamWriter =OutputStreamWriter(context.openFileOutput(fileName, Context.MODE_PRIVATE))// Esta variable es para poder escribir desde el celular outputStreamWriter.write(arguments.toString())// Escribe todos los argumentos que se le pasen outputStreamWriter.close()// Cerramos nuestra conexion al sistema de archivos del celular}catch(exception: IOException){ Log.e("SaveCommand","File write failed: $exception")}}}
ReadCommand:
package com.cristianvillamil.platziwallet.ui.commands
import android.content.Context
import android.util.Log
import java.io.BufferedReader
import java.io.InputStreamReader
class ReadCommand : FileCommand {overridefunexecute(context: Context, fileName: String,vararg arguments: String){var fileString =""// Almacena lo que escribimos en la consola que despues ira en el archivoval inputStream = context.openFileInput(fileName)// Abrimos una conexion con el sistema de archivos para solo lecturaval stringBuilder =StringBuilder()// Hacemos un append en todos los archivos que vamos trayendo de la memoriaval inputStreamReader =InputStreamReader(inputStream)// Nos ayuda a leer los archivosval bufferedReader =BufferedReader(inputStreamReader)// Nos permite leer linea por linea del archivo bufferedReader.forEachLine{ stringBuilder.append("\n").append(it)}// Por cada linea agrega un salto de linea al final fileString = stringBuilder.toString()// Lo convertimos a string Log.e("ReadedFile", fileString)// Mostramos en el log los archivos}}
MainActivity: Este es el archivo raíz del proyecto
package com.cristianvillamil.platziwallet
import android.os.Bundle
import com.google.android.material.bottomnavigation.BottomNavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.cristianvillamil.platziwallet.ui.commands.FileCommandsManager
import com.cristianvillamil.platziwallet.ui.commands.ReadCommand
import com.cristianvillamil.platziwallet.ui.commands.SaveCommand
class MainActivity :AppCompatActivity(){overridefunonCreate(savedInstanceState: Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val navView: BottomNavigationView =findViewById(R.id.nav_view)val navController =findNavController(R.id.nav_host_fragment) navView.setupWithNavController(navController)// Commandsval commandsManager =FileCommandsManager()// Instanciamos el managerval saveCommand =SaveCommand()// Instanciamos el comando de guardadoval readCommand =ReadCommand()// Instanciamos el comando de lectura commandsManager.putCommand("SaveCommand", saveCommand)// Registramos el comando commandsManager.putCommand("ReadCommand", readCommand)// Resgistramos el comando commandsManager.getCommand("SaveCommand").execute(this,"exampleFile","Hola Mundo","Platzi Wallet")// Generamos el archivo commandsManager.getCommand("ReadCommand").execute(this,"exampleFile")// Leemos el archivo}}
Identar codigo
En Android Studio, la indentación es el proceso de organizar y alinear el código fuente de manera que sea más legible y siga un formato consistente. Para indentar el código en Android Studio, sigue estos pasos:
Seleccionar el código: Primero, selecciona el código que deseas indentar. Puedes seleccionar todo el archivo o solo una parte específica.
Usar el atajo de teclado: El atajo de teclado más común para indentar el código en Android Studio es Ctrl + Alt + L en Windows o Cmd + Option + L en macOS. Esto formateará automáticamente el código seleccionado según las convenciones de estilo configuradas en Android Studio.
Usar el menú: También puedes indentar el código a través del menú. Ve a Code en la parte superior de la ventana de Android Studio y selecciona la opción Reformat Code. Esto abrirá un cuadro de diálogo donde puedes ajustar las opciones de formato antes de aplicar la indentación.
Configurar reglas de estilo: Android Studio permite personalizar las reglas de estilo de indentación según tus preferencias. Para hacerlo, ve a File > Settings (o Android Studio > Preferences en macOS), luego busca "Editor" y selecciona "Code Style". Aquí puedes configurar las reglas de estilo para Java, Kotlin y otros lenguajes compatibles con Android Studio.
Aplicar automáticamente al escribir: Puedes configurar Android Studio para que aplique automáticamente la indentación mientras escribes código. Ve a File > Settings (o Android Studio > Preferences en macOS), luego busca "Editor" y selecciona "General". Marca la casilla que dice "Auto-indent on typing" o una opción similar.