0x7E5 Raciocinando sobre o principal

Sobre mim

SaudaçÔes a todos. Meu nome Ă© Vyacheslav, trabalho na ĂĄrea de TI hĂĄ 11 anos na direção do Android. Toquei e acariciei dinossauros na cara do Android 1.5 e 1.6, passei por todas as etapas da formação do MVP MVVM Retrofit e muitas outras bibliotecas. Olhei para o meu cĂłdigo antigo como um monte de g ... muitas vezes e continuo aprendendo e desenvolvendo. Consegui aprender mais de uma dĂșzia, nĂŁo tenho medo dessa palavra, caras “fortes”, com bom potencial e cabeça sobre os ombros, no processo de treinamento foram formadas regras e recomendaçÔes que quero compartilhar . 





Sobre o artigo

Recentemente, encontrei muitos projetos de complexidade variada e vejo um problema natural. Os programadores iniciantes nĂŁo veem o valor de conceitos como Clean Code, KISS e SOLID. Podemos concordar que o Clean Code estĂĄ longe de ser para iniciantes, mas acho que em termos gerais, o conhecimento dessa abordagem Ă© necessĂĄrio. Os programadores intermediĂĄrios nĂŁo aplicam totalmente essas abordagens. Os programadores experientes muitas vezes se aprofundam muito nos detalhes e se esquecem das coisas mais importantes. Para iniciantes: este artigo o ajudarĂĄ a coletar regras para si mesmo Ă s quais vale a pena prestar atenção. 





Para os experientes: redefina seus pontos de vista ou aprofunde-se nos detalhes das abordagens de codificação modernas.





Para profissionais: olhe para as abordagens modernas de um Ăąngulo diferente (espero). Às vezes, Ă© Ăștil dar um passo para trĂĄs e verificar se vocĂȘ estĂĄ no caminho certo.





, , . . Clean Code.





Clean Code

, , . 





“Clean Code”. , . . - , ( ). - , . : “ ”. - 2 , - - ”. , - . . , 100 . . 2 ? - , - , . .. - ,  . “transformDateToString” “transDTS”. “ ” - “”, “ ” - . “” “”, “” . . , . : - .





KISS 

KISS (keep it simple, stupid). , . - , , , . . SOLID, , , , - , . . 





    interface Factory<out T> {
       fun create(): T
    }
    typealias PrinterFun = (String) -> Unit

    interface PrinterFactory : Factory<PrinterFun>
    interface MessageFactory : Factory<String>
    interface MessagePrinter {
       fun print(pf: PrinterFactory, mf: MessageFactory)
    }

    class PrinterFactoryImpl : PrinterFactory {
       override fun create(): PrinterFun = ::print
    }

    class MessageFactoryImpl : MessageFactory {
   companion object {
       const val DEFAULT_MESSAGE = "Hello World"
   }

   override fun create(): String = DEFAULT_MESSAGE


   class MessagePrinterImpl : MessagePrinter {
       override fun print(pf: PrinterFactory, mf: MessageFactory) {
           pf.create().invoke(mf.create())
       }
   }

   class ImplProvider {
       private val impls = HashMap<KClass<out Any>, Any>()
       fun <T : Any> setImpl(clazz: KClass<T>, t: T) {
           impls[clazz] = t
       }

       fun <T : Any> getImpl(clazz: KClass<T>): T {
           return (impls[clazz] as? T) ?: throw Exception("No impl")
       }
   }

   fun main(args: Array<String>) {
       val implProvider = ImplProvider()
       implProvider.setImpl(PrinterFactory::class, PrinterFactoryImpl())
       implProvider.setImpl(MessageFactory::class, MessageFactoryImpl())
       implProvider.setImpl(MessagePrinter::class, MessagePrinterImpl())

       implProvider.getImpl(MessagePrinter::class)
               .print(implProvider.getImpl(PrinterFactory::class),
                       implProvider.getImpl(MessageFactory::class))
   }
      
      



“Hello world”? “” - . 





    class TimeFormatter {
       private val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
       fun formatTime() = timeFormat.format(Date())
    }
      
      



. (UNIT ) . , . .





SOLID

“” : SOLID! , , - . . , - , - , , . - , . “ ”, “ ”, .





S - single responsibility

[WIKI] (single responsibility principle). . , , .





: “ ”.





“ ”, - , , . 20 1-2 (TextEditUtils, TextTransformUtils, TextConcatUtils ) - TextUtils . , , . GOD-CLASS . , , . . - . , - . , - ( , ). 





O - open–closed

[WIKI] /. « 
 , ».





“ ( )”. , , . 





. “ ?”. - , ? , - , . . - - , . :





open class UiComponent() {
   var mode : Int = 0
   fun showTextAndImage(text:String, image: Image){
       mode = 0
       ...
   }
   fun showButton(text:String, action: Runnable){
       mode = 1
       ...
   }
   ...
}
      
      



, -:





class MyUiComponent(): UiComponent(){
   fun doMagic(){mode = 3}
}
      
      



- “ ”, “? , ?” . , , , , , . “mode” , - . , ( ), .





, , , , .





L - Liskov substitution

[WIKI] . « ». .





, . , . . “ ”.  , , , . . 





. . “Downloader” “downloadFile(url)”. , , . “Downloader” , . ( ) Downloadable:





class DownloadManager() {
   fun download(downloadable: Downloadable) {
       val stream = downloadable.openStream()
       val file = File(downloadable.getFileName())
       //   
   }
}

interface Downloadable {
   fun openStream(): InputStream
   fun getFileName(): String
}

class SimpleDownloadableFile(val name: String, 
                             val url: String) : Downloadable {
   override fun openStream() = URL(url).openStream()
   override fun getFileName() = name
}

class HeaderFile(val name: String, 
                 val url: String, 
                 val headers: Map<String, String>) : Downloadable {
   override fun openStream(): InputStream { 
            /*    */ 
   }
   override fun getFileName() = name
}
      
      



( ) ( , + ) 





- , . . - : 





interface Something
interface SomethingSpecific : Something
interface WritableSomething : SomethingSpecific {
   fun writeToFile()
}

interface GetableWritable<T> : WritableSomething {
   fun obtain(): T
}

abstract class ObtainableFile(val name: String) : GetableWritable<File> {
   override fun obtain() = File(name)
   override fun writeToFile() = obtain().write(getStream())
   abstract fun getStream(): InputStream
}

class UrlFile(url: String, name: String) : ObtainableFile(name) {
   override fun getStream(): InputStream = URL(url).openStream()
}
      
      



, . , KISS.  PS: 






I - interface segregation

[WIKI] . « , , , ».





. - “ ” . - “”, “interface / abstract class”. 





“” “ ” . 1000 , , java interface, . 





“” - , . ( Utils) . . “ ”, .





. “” “”, S (Single responsibility). Open-close . Liskov substitution .





D - dependency inversion

[WIKI] . « . - ».





, , . . . , . : single responsibility, ( , , , ).  : . , Liskov substitution “”, ,  . 





: . :





open class ServerManager {
   open fun getData(): String = "  "
}

open class CacheManager {
   open fun saveData(data: String) {/*  /  */}
}

class DataManager{
   fun getDataAndCache(){
       val data = ServerManager().getData()
       CacheManager().saveData(data)
   }
}
      
      



, / “”, .





- . DataManager : 





class DataManager(private val serverManager: ServerManager,
                  private val cacheManager: CacheManager) {
   fun getDataAndCache() {
       val data = serverManager.getData()
       cacheManager.saveData(data)
   }
}
      
      



. , ( , - ). 





Clean Architecture , . “” :





interface ServerManager {
   fun getData(): String
}
open class ServerManagerImpl : ServerManager {
   override fun getData(): String = "  "
}

interface CacheManager {
   fun saveData(data: String)
}
open class CacheManagerImpl : CacheManager {
   override fun saveData(data: String) {
       /*  /  */
   }
}

interface DataManager {
   fun getDataAndCache()
}
class DataManagerImpl(
       private val serverManager: ServerManager,
       private val cacheManager: CacheManager,
) : DataManager {
   override fun getDataAndCache() {
       val data = serverManager.getData()
       cacheManager.saveData(data)
   }
}

fun foo(){
   val dataManager: DataManager = DataManagerImpl(
           ServerManagerImpl(),
           CacheManagerImpl()
   )
   dataManager.getDataAndCache()
}
      
      



( ) , ( ). 





(Dagger, Koin, ServiceLocator ), . , , :





interface TextProvider {
   fun getText(): String
}

class SimpleTextProvider(private val text: String) : TextProvider {
   override fun getText(): String = text
}

class Printer(private val textProvider: TextProvider) {
   fun printText() {
       println(textProvider.getText())
   }
}

fun main() {
   Printer(SimpleTextProvider("text")).printText()
}
      
      



, , SOLID , Dependency injection. . . , - KISS.





“”, , . - . “ ” , ,   . ( - Adapter-, , ).





, “ ”, , . . , . - . - . , , - : . (MVP, MVVM ) , ( -, - 
). , . , . . 





“Clean architecture”. . , - . “Clean architecture ”, , , . - . Hello World , ?





, , ( , ). “”. - , .





“ ”

“ ?”, . , , : . , , . . . , , ? - 2 , .. 
 . - . ? , , “” . . 





. .





- . “ ”, “ ”. “ ” . “ ” - . : - , , .





- . ( ) . , . “” ( /). 





Para finalizar, gostaria de relembrar um conselho muito Ăștil encontrado na Internet: “Escreva o cĂłdigo como se fosse lido por um manĂ­aco que sabe onde vocĂȘ mora”. Escreva um bom cĂłdigo e que cafĂ© e biscoitos acompanhem vocĂȘ. 








All Articles