Ă propos de moi
Salutations Ă tous. Je m'appelle Vyacheslav, je travaille dans l'informatique depuis 11 ans sous la direction d'Android. J'ai touchĂ© et caressĂ© des dinosaures face Ă Android 1.5 et 1.6, j'ai traversĂ© toutes les Ă©tapes de la formation de MVP MVVM Retrofit et de nombreuses autres bibliothĂšques. J'ai regardĂ© mon ancien code comme un tas de g ... plusieurs fois et continue Ă apprendre et Ă se dĂ©velopper. J'ai rĂ©ussi Ă en apprendre plus d'une dizaine, je n'ai pas peur de ce mot, des mecs «forts», avec un bon potentiel et une tĂȘte sur les Ă©paules, en cours de formation, des rĂšgles et recommandations se sont formĂ©es, que je souhaite partager .
Ă propos de l'article
RĂ©cemment, je suis tombĂ© sur de nombreux projets de complexitĂ© variable et je vois un problĂšme naturel. Les programmeurs novices ne voient pas la valeur de concepts tels que Clean Code, KISS et SOLID. Nous pouvons convenir que Clean Code est loin d'ĂȘtre pour les dĂ©butants, mais je pense que d'une maniĂšre gĂ©nĂ©rale, la connaissance de cette approche est nĂ©cessaire. Les programmeurs intermĂ©diaires n'appliquent pas pleinement ces approches. Les programmeurs expĂ©rimentĂ©s vont souvent trop loin dans les dĂ©tails et oublient les choses les plus importantes. Pour les dĂ©butants: cet article vous aidera Ă collecter des rĂšgles qui mĂ©ritent d'ĂȘtre Ă©tudiĂ©es.
Pour les expérimentés: redéfinissez vos points de vue ou plongez dans les détails des approches de codage modernes.
Pour les professionnels: regardez les approches modernes sous un angle diffĂ©rent (espĂ©rons-le). Parfois, il est utile de prendre du recul et de s'assurer que vous ĂȘtes sur la bonne voie.
, , . . 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 , .. ⊠. - . ? , , ââ . .
. .
- . â â, â â. â â . â â - . : - , , .
- . ( ) . , . ââ ( /).
En conclusion, je voudrais rappeler un conseil trĂšs utile trouvĂ© sur Internet: «Ăcrivez le code comme s'il devait ĂȘtre lu par un maniaque qui sait oĂč vous habitez». Ăcrivez un bon code et que le cafĂ© et les biscuits vous accompagnent.