Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Seni Bina Bersih Berjuang di Golang dan Perkara yang Berfungsi Lebih Baik

Mengapa Seni Bina Bersih Berjuang di Golang dan Perkara yang Berfungsi Lebih Baik

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-11-07 01:59:02579semak imbas

Why Clean Architecture Struggles in Golang and What Works Better

Golang telah mengukir reputasi kukuh sebagai bahasa yang pantas dan cekap yang mengutamakan kesederhanaan, yang merupakan salah satu sebab mengapa ia begitu biasa digunakan untuk perkhidmatan bahagian belakang, perkhidmatan mikro dan perkakasan infrastruktur. Walau bagaimanapun, apabila lebih banyak pembangun daripada bahasa seperti Java dan C# beralih kepada Go, persoalan tentang melaksanakan Seni Bina Bersih timbul. Bagi mereka yang biasa menggunakan pendekatan berasaskan lapisan Clean Architecture untuk menstrukturkan aplikasi, ia boleh berasa intuitif untuk menggunakan prinsip yang sama pada Go. Walau bagaimanapun, seperti yang akan kita terokai, cubaan untuk melaksanakan Seni Bina Bersih dalam Go sering menjadi bumerang. Sebaliknya, kita akan melihat struktur yang disesuaikan untuk kekuatan Go yang lebih mudah, fleksibel dan sejajar dengan falsafah "kekalkan mudah" Go.

Mengapa Seni Bina Bersih Terasa Tidak Sesuai di Go

Matlamat Seni Bina Bersih, yang diperjuangkan oleh Uncle Bob (Robert C. Martin), adalah untuk mencipta perisian yang modular, boleh diuji dan mudah dikembangkan. Ini dicapai dengan menguatkuasakan pengasingan kebimbangan antara lapisan, dengan logik perniagaan teras diasingkan daripada kebimbangan luaran. Walaupun ini berfungsi dengan baik dalam bahasa berorientasikan objek tinggi seperti Java, ia memperkenalkan geseran dalam Go. Inilah sebabnya:

1. Minimalisme Go Melawan Abstraksi Berlebihan

Dalam Go, terdapat penekanan yang kuat pada kebolehbacaan, kesederhanaan dan pengurangan overhed. Seni Bina Bersih memperkenalkan lapisan demi lapisan abstraksi: antara muka, penyongsangan kebergantungan, suntikan kebergantungan kompleks dan lapisan perkhidmatan untuk logik perniagaan. Walau bagaimanapun, lapisan tambahan ini cenderung menambah kerumitan yang tidak perlu apabila dilaksanakan dalam Go.

Mari kita ambil Kubernetes sebagai contoh. Kubernetes ialah projek besar yang dibina dalam Go, tetapi ia tidak bergantung pada prinsip Seni Bina Bersih. Sebaliknya, ia merangkumi struktur rata, berorientasikan fungsi yang memfokuskan pada pakej dan subsistem. Anda boleh melihat ini dalam repositori Kubernetes GitHub, di mana pakej disusun mengikut fungsi dan bukannya lapisan tegar. Dengan mengumpulkan kod berdasarkan kefungsian, Kubernetes mencapai modulariti tinggi tanpa abstraksi yang kompleks.

Falsafah Go mengutamakan kepraktisan dan kepantasan. Pencipta bahasa secara konsisten menyokong untuk mengelakkan terlalu banyak arkitek, memihak kepada pelaksanaan yang mudah. Jika abstraksi tidak benar-benar diperlukan, ia tidak termasuk dalam kod Go. Pencipta Go malah mereka bentuk bahasa tanpa warisan untuk mengelakkan perangkap kejuruteraan berlebihan, menggalakkan pembangun untuk memastikan reka bentuk mereka bersih dan jelas.

2. Suntikan Ketergantungan adalah Terhad oleh Reka Bentuk

Clean Architecture sangat bergantung pada Dependency Injection untuk memisahkan lapisan yang berbeza dan menjadikan modul lebih boleh diuji. Dalam bahasa seperti Java, DI ialah bahagian semula jadi ekosistem terima kasih kepada rangka kerja seperti Spring. Rangka kerja ini mengendalikan DI secara automatik, membolehkan anda menyambung kebergantungan bersama-sama dengan mudah, tanpa mengacaukan kod anda.

Walau bagaimanapun, Go tidak mempunyai sistem DI asli, dan kebanyakan perpustakaan DI untuk Go sama ada terlalu kompleks atau berasa unidiomatik. Go bergantung pada suntikan pergantungan eksplisit melalui fungsi pembina atau parameter fungsi, memastikan kebergantungan jelas dan mengelakkan "ajaib" tersembunyi dalam bekas DI. Pendekatan Go menjadikan kod lebih jelas, tetapi ini juga bermakna jika anda memperkenalkan terlalu banyak lapisan, pengurusan pergantungan menjadi tidak terurus dan bertele-tele.

Dalam Kubernetes, sebagai contoh, anda tidak melihat rangka kerja DI atau bekas DI yang kompleks. Sebaliknya, kebergantungan disuntik dengan cara yang mudah menggunakan pembina. Reka bentuk ini memastikan kod telus dan mengelakkan perangkap rangka kerja DI. Golang menggalakkan penggunaan DI hanya apabila ia benar-benar masuk akal, itulah sebabnya Kubernetes mengelak daripada mencipta antara muka dan kebergantungan yang tidak perlu hanya untuk mengikuti corak.

3. Pengujian Menjadi Lebih Kompleks dengan Terlalu Banyak Lapisan

Satu lagi cabaran dengan Seni Bina Bersih dalam Go ialah ia boleh membuat ujian tidak perlu rumit. Di Jawa, sebagai contoh, Seni Bina Bersih menyokong ujian unit yang mantap dengan penggunaan olok-olok yang banyak untuk kebergantungan. Mengejek membolehkan anda mengasingkan setiap lapisan dan mengujinya secara bebas. Walau bagaimanapun, dalam Go, membuat olok-olok boleh menjadi menyusahkan, dan komuniti Go secara amnya mengutamakan ujian atau ujian penyepaduan dengan pelaksanaan sebenar di mana mungkin.

Dalam projek Go gred pengeluaran, seperti Kubernetes, ujian tidak dikendalikan dengan mengasingkan setiap komponen tetapi dengan memfokuskan pada penyepaduan dan ujian hujung ke hujung yang merangkumi senario kehidupan sebenar. Dengan mengurangkan lapisan abstraksi, projek Go seperti Kubernetes mencapai liputan ujian yang tinggi sambil memastikan ujian hampir kepada gelagat sebenar, yang menghasilkan lebih keyakinan apabila digunakan dalam pengeluaran.

Pendekatan Seni Bina Terbaik untuk Golang

Jadi, jika Seni Bina Bersih tidak sesuai dengan Go, apakah yang patut? Jawapannya terletak pada struktur yang lebih ringkas dan lebih berfungsi yang menekankan pakej dan memfokuskan pada modulariti berbanding lapisan yang ketat. Satu corak seni bina yang berkesan untuk Go adalah berdasarkan Seni Bina Heksagon, selalunya dikenali sebagai Pelabuhan dan Penyesuai. Seni bina ini membolehkan modulariti dan fleksibiliti tanpa lapisan yang berlebihan.

Reka Letak Projek Piawaian Golang ialah titik permulaan yang bagus untuk mencipta projek sedia pengeluaran dalam Go. Struktur ini menyediakan asas untuk menyusun kod mengikut tujuan dan fungsi dan bukannya oleh lapisan seni bina.

Struktur Projek Go: Contoh Praktikal

Anda betul sekali! Menstrukturkan projek Go dengan pendekatan berfokuskan pakej, di mana fungsi dipecahkan mengikut pakej dan bukannya struktur folder berlapis, sejajar dengan lebih baik dengan prinsip reka bentuk Go. Daripada mencipta direktori peringkat atas mengikut lapisan (cth., pengawal, perkhidmatan, repositori), ia lebih idiomatik dalam Go untuk mencipta pakej padu, masing-masing merangkum model, perkhidmatan dan repositorinya sendiri. Pendekatan berasaskan pakej ini mengurangkan gandingan dan mengekalkan kod modular, yang penting untuk aplikasi Go gred pengeluaran.

Mari lihat struktur yang diperhalusi, berpusatkan pakej yang sesuai untuk Go:

/myapp
   /cmd                   // Entrypoints for different executables (e.g., main.go)
      /myapp-api
         main.go          // Entrypoint for the main application
   /config                // Configuration files and setup
   /internal              // Private/internal packages (not accessible externally)
      /user               // Package focused on user-related functionality
         models.go        // Data models and structs specific to user functionality
         service.go       // Core business logic for user operations
         repository.go    // Database access methods for user data
      /order              // Package for order-related logic
         models.go        // Data models for orders
         service.go       // Core order-related logic
         repository.go    // Database access for orders
   /pkg                   // Shared, reusable packages across the application
      /auth               // Authorization and authentication package
      /logger             // Custom logging utilities
   /api                   // Package with REST or gRPC handlers
      /v1
         user_handler.go  // Handler for user-related endpoints
         order_handler.go // Handler for order-related endpoints
   /utils                 // General-purpose utility functions and helpers
   go.mod                 // Module file

Komponen Utama dalam Struktur Berasaskan Pakej

  1. /cmd

Folder ini ialah lokasi konvensional untuk pintu masuk aplikasi. Setiap subfolder di sini mewakili boleh laku yang berbeza untuk apl. Contohnya, dalam seni bina perkhidmatan mikro, setiap perkhidmatan boleh mempunyai direktori sendiri di sini dengan main.gonya. Kod di sini hendaklah minimum, hanya bertanggungjawab untuk bootstrap dan menyediakan kebergantungan.

  1. /config

Menyimpan fail konfigurasi dan logik persediaan, seperti memuatkan pembolehubah persekitaran atau konfigurasi luaran. Pakej ini juga boleh menentukan struktur untuk konfigurasi aplikasi.

  1. /dalaman

Di sinilah logik teras aplikasi berada, dibahagikan kepada pakej berdasarkan kefungsian. Go mengehadkan akses kepada pakej dalaman daripada modul luaran, memastikan pakej ini peribadi kepada aplikasi. Setiap pakej (cth., pengguna, pesanan) adalah serba lengkap, dengan model, perkhidmatan dan repositorinya sendiri. Ini adalah kunci kepada falsafah pengkapsulan Go tanpa lapisan yang berlebihan.

  • /dalaman/pengguna – Mengurus semua fungsi berkaitan pengguna, termasuk model (struktur data), perkhidmatan (logik perniagaan) dan repositori (interaksi pangkalan data). Ini mengekalkan logik berkaitan pengguna dalam satu pakej, menjadikannya mudah untuk diselenggara.

  • /dalaman/pesanan – Begitu juga, pakej ini merangkumi kod berkaitan pesanan. Setiap kawasan berfungsi mempunyai model, perkhidmatan dan repositorinya sendiri.

  1. /pkg

pkg memegang komponen boleh guna semula yang digunakan di seluruh aplikasi tetapi tidak khusus untuk mana-mana satu pakej. Perpustakaan atau utiliti yang boleh digunakan secara bebas, seperti pengesahan untuk pengesahan atau pembalak untuk pengelogan tersuai, disimpan di sini. Jika pakej ini amat berguna, ia juga boleh diekstrak ke modul mereka sendiri kemudian hari.

  1. /api

Pakej API berfungsi sebagai lapisan untuk pengendali HTTP atau gRPC. Pengendali di sini mengendalikan permintaan masuk, menggunakan perkhidmatan dan membalas respons. Pengumpulan pengendali mengikut versi API (cth., v1) ialah amalan yang baik untuk membuat versi dan membantu memastikan perubahan masa depan diasingkan.

  1. /utils

Utiliti tujuan am yang tidak terikat pada mana-mana pakej tertentu tetapi berfungsi untuk tujuan pemotongan silang merentas pangkalan kod (cth., penghuraian tarikh, manipulasi rentetan). Adalah berguna untuk memastikan ini minimum dan fokus pada fungsi utiliti semata-mata.

Contoh Tata Letak Kod untuk Pakej pengguna

Untuk menggambarkan struktur, berikut lihat lebih dekat rupa pakej pengguna:

models.go

/myapp
   /cmd                   // Entrypoints for different executables (e.g., main.go)
      /myapp-api
         main.go          // Entrypoint for the main application
   /config                // Configuration files and setup
   /internal              // Private/internal packages (not accessible externally)
      /user               // Package focused on user-related functionality
         models.go        // Data models and structs specific to user functionality
         service.go       // Core business logic for user operations
         repository.go    // Database access methods for user data
      /order              // Package for order-related logic
         models.go        // Data models for orders
         service.go       // Core order-related logic
         repository.go    // Database access for orders
   /pkg                   // Shared, reusable packages across the application
      /auth               // Authorization and authentication package
      /logger             // Custom logging utilities
   /api                   // Package with REST or gRPC handlers
      /v1
         user_handler.go  // Handler for user-related endpoints
         order_handler.go // Handler for order-related endpoints
   /utils                 // General-purpose utility functions and helpers
   go.mod                 // Module file

perkhidmatan.pergi

// models.go - Defines the data structures related to users

package user

type User struct {
    ID       int
    Name     string
    Email    string
    Password string
}

repository.go

// service.go - Contains the core business logic for user operations

package user

type UserService struct {
    repo UserRepository
}

// NewUserService creates a new instance of UserService
func NewUserService(repo UserRepository) *UserService {
    return &UserService{repo: repo}
}

func (s *UserService) RegisterUser(name, email, password string) error {
    // Business logic for registering a user
    newUser := User{Name: name, Email: email, Password: password}
    return s.repo.Save(newUser)
}

Mengapa Struktur Berasaskan Pakej Ini Sesuai untuk Go

Struktur ini sejajar dengan simpulan bahasa Go:

  1. Pengenkapsulan

Dengan menyusun pakej berdasarkan kefungsian, kod tersebut secara semula jadi terkapsul dan modular. Setiap pakej memiliki model, perkhidmatan dan repositorinya, mengekalkan kod pada padu dan sangat modular. Ini menjadikannya lebih mudah untuk menavigasi, memahami dan menguji pakej individu.

  1. Antara Muka Minimum

Antara muka hanya digunakan pada sempadan pakej (cth., UserRepository), di mana ia paling sesuai untuk ujian dan fleksibiliti. Pendekatan ini mengurangkan kekusutan antara muka yang tidak diperlukan, yang boleh menjadikan kod Go lebih sukar untuk dikekalkan.

  1. Suntikan Ketergantungan Eksplisit

Pergantungan disuntik melalui fungsi pembina (cth., NewUserService). Ini memastikan kebergantungan jelas dan mengelakkan keperluan untuk rangka kerja suntikan kebergantungan yang kompleks, kekal berpegang pada reka bentuk fokus kesederhanaan Go.

  1. Kebolehgunaan semula dalam /pkg

Komponen seperti auth dan logger dalam direktori pkg boleh dikongsi merentas pakej, menggalakkan kebolehgunaan semula tanpa gandingan yang berlebihan.

  1. Kosongkan Struktur API

Dengan mengelompokkan pengendali di bawah /api, adalah mudah untuk menskalakan lapisan API dan menambah versi atau pengendali baharu apabila aplikasi berkembang. Setiap pengendali boleh menumpukan perhatian pada pengendalian permintaan dan penyelarasan dengan perkhidmatan, memastikan kod modular dan bersih.

Struktur berpusatkan pakej ini membolehkan anda membuat skala semasa anda menambahkan lebih banyak domain (cth., produk, inventori), masing-masing dengan model, perkhidmatan dan repositorinya sendiri. Pemisahan mengikut domain sejajar dengan cara idiomatik Go dalam mengatur kod, kekal berpegang pada kesederhanaan dan kejelasan berbanding lapisan tegar.

Pendapat dan Pengalaman Dunia Nyata

Dalam pengalaman saya bekerja dengan Go, Clean Architecture sering merumitkan pangkalan kod tanpa menambah nilai yang ketara. Seni Bina Bersih cenderung masuk akal apabila membina aplikasi gred perusahaan yang besar dalam bahasa seperti Java, di mana terdapat banyak sokongan terbina dalam untuk DI, dan mengurus struktur warisan mendalam adalah keperluan biasa. Walau bagaimanapun, minimalisme Go, pemikiran yang mengutamakan kesederhanaan, dan pendekatannya yang mudah untuk penyelarasan dan pengendalian ralat mewujudkan ekosistem yang berbeza sama sekali.

Kesimpulan: Hayati Seni Bina Idiomatik Go

Jika anda datang dari latar belakang Java, mungkin tergoda untuk menggunakan Seni Bina Bersih untuk Pergi. Walau bagaimanapun, kekuatan Go terletak pada kesederhanaan, ketelusan dan modulariti tanpa abstraksi berat. Seni bina yang ideal untuk Go mengutamakan pakej yang disusun mengikut fungsi, antara muka minimum, DI eksplisit, ujian realistik dan penyesuai untuk fleksibiliti.

Apabila mereka bentuk projek Go, lihat contoh dunia sebenar seperti Kubernetes, Bilik Kebal dan Reka Letak Projek Piawaian Golang. Ini mempamerkan betapa hebatnya Go apabila seni bina merangkumi kesederhanaan berbanding struktur tegar. Daripada cuba menjadikan Go sesuai dengan acuan Seni Bina Bersih, gunakan seni bina yang mudah dan cekap seperti Go itu sendiri. Dengan cara ini, anda sedang membina pangkalan kod yang bukan sahaja idiomatik tetapi lebih mudah difahami, diselenggara dan skala.

Atas ialah kandungan terperinci Mengapa Seni Bina Bersih Berjuang di Golang dan Perkara yang Berfungsi Lebih Baik. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn