自分自身について
皆さんこんにちは。私の名前はVyacheslavです。Androidの方向で11年間ITに携わっています。私はAndroid1.5と1.6に直面して恐竜に触れて撫で、MVP MVVMRetrofitと他の多くのライブラリの形成のすべての段階を通過しました。私の古いコードをgの束として見ました...何度も、それでも学習と開発を続けています。私は何とか十数人以上を学ぶことができました。トレーニングの過程で、可能性が高く、頭を抱えた「強い」人という言葉を恐れません。ルールと推奨事項が形成されました。これを共有したいと思います。 。
記事について
最近、さまざまな複雑さのプロジェクトに出くわしましたが、自然な問題があります。初心者のプログラマーは、Clean Code、KISS、SOLIDなどの概念の価値を理解していません。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 , .. … . - . ? , , “” . .
. .
- . “ ”, “ ”. “ ” . “ ” - . : - , , .
- . ( ) . , . “” ( /).
結論として、インターネットで見つけた非常に有用なアドバイスを思い出したいと思います。「あなたがどこに住んでいるかを知っているマニアックが読むようにコードを書いてください」。良いコードを書いてください。そうすれば、コーヒーとクッキーがあなたと一緒に来るかもしれません。