首頁  >  文章  >  後端開發  >  重構一個期望一件事期望很多事情的對象

重構一個期望一件事期望很多事情的對象

WBOY
WBOY轉載
2024-02-08 23:39:08381瀏覽

重構一個期望一件事期望很多事情的對象

php小編魚仔在程式設計中,我們常常會遇到一個物件希望承擔多個職責的情況。這種物件稱為"重構一個期望一件事期望很多事情的物件"。這樣的物件通常會導致程式碼臃腫、耦合度高,難以維護和擴展。在這篇文章中,我們將探討如何重構這樣的對象,使其更加清晰、靈活且易於維護。讓我們一起來看看吧!

問題內容

我正在努力更新 Go 程式碼庫。我們公司有一個中央資料存儲,虛構地稱為 DataStore,您可以將其發佈到各種資料集或模式或從中讀取。我們特定的程式碼庫有一些程式碼將特定的資料集/模式耦合到 DataStore 實作。我需要重構此程式碼以能夠寫入其他(可能還有更多)資料集。

在下面的程式碼中,dataStoreSchema 表示單一架構,例如「Customers」資料。但我有其他模式,例如“訂單”,或任何具有我想要寫入的不同欄位的模式。

transformEvent 取得將傳遞到 DataStore 的數據,並執行一些邏輯來建立 dataStoreSchema 對象,然後將其寫入雲端中的實際 DataStore。

我想寫入資料儲存上的潛在任何模式,而不僅僅是該實作所耦合的模式。

type Parameters struct {
    SchemaName              string
    Host                    string
    Secret                  string
}

type DataStore struct {
    params                *Parameters
    url                   string
    request               *http.Client
}

// imagine this defines an Order, but other schemas might be for Customer
type dataStoreSchema struct {
    eventUrl string `json:"url"`
    objectID string `json:"object_id"`
}

func New(parameters) (*DataStore, error) {
    // implementation

    return &stream, nil
}

// takes input and converts it into a schema object that can be written to the datastore
func (ds *DataStore) transformEvent(...) dataStoreSchema {

    // .... implementation

    return dataStoreSchema{
        eventUrl: url,
        objectID: objectId,
    }
}

func (ds *DataStore) writeEvents(...) error {

    // .... implementation
    payload := ds.transformEvent(event)
        

    ds.produce(payload)
}

func (ds *DataStore) produce(msg []events) {
        ds.WriteToDatastore(msg)
}

現在的行為是這樣的

myDatasetClient := DataStore.New(params)
myDatasetClient.write(<-messages chan)

但我希望能夠做這樣的事情

myDatasetClient1 := DataStore.New(params{schema1, transformEvent1})
myDatasetClient2 := DataStore.New(params{schema2, transformEvent2})
myDatasetClient3 := DataStore.New(params{schema3, transformEvent3})

或任何Go 術語中最有意義的內容

解決方法

如果我理解正確,您當前的實作透過dataStoreSchema 結構和transformEvent 方法與特定模式緊密耦合。 transformEvent 方法接受輸入並將其轉換為 dataStoreSchema 對象,然後將其寫入 DataStore。

您可能希望寫入資料儲存上的任何模式,而不僅僅是當前實作所耦合的模式。

myDatasetClient1 := DataStore.New(params{schema1, transformEvent1})
myDatasetClient2 := DataStore.New(params{schema2, transformEvent2})
myDatasetClient3 := DataStore.New(params{schema3, transformEvent3})

意義:您想要建立不同的DataStore 用戶端,每個用戶端與不同的schema 和對應的轉換函數相關聯(transformEvent1transformEvent2transformEvent3)。
這應該意味著將轉換邏輯與 DataStore 結構解耦,允許使用不同的轉換函數處理不同的模式。

您可以使用介面進行不同的架構轉換並修改 ParametersDataStore 結構:

package main

import (
    "net/http"
)

// Define a Transformer function type that takes an event of type E and returns a schema of type S
type Transformer[E any, S any] func(event E) S

type Parameters[E any, S any] struct {
    SchemaName  string
    Host        string
    Secret      string
    TransformFn Transformer[E, S]
}

type DataStore[E any, S any] struct {
    params  *Parameters[E, S]
    url     string
    request *http.Client
}

// Define structs for different schemas and events
type OrderSchema struct {
    eventUrl string `json:"url"`
    objectID string `json:"object_id"`
    // other fields
}

type OrderEvent struct {
    // fields
}

type CustomerSchema struct {
    eventUrl string `json:"url"`
    objectID string `json:"object_id"`
    // other fields
}

type CustomerEvent struct {
    // fields
}

// New creates a new DataStore
func New[E any, S any](params Parameters[E, S]) (*DataStore[E, S], error) {
    // implementation
    return &DataStore[E, S]{params: &params}, nil
}

func (ds *DataStore[E, S]) transformEvent(event E) S {
    return ds.params.TransformFn(event)
}

// rest of the code remains the same

// Usage:
func main() {
    orderTransformFn := func(event OrderEvent) OrderSchema {
        // implementation for Order schema
    }

    customerTransformFn := func(event CustomerEvent) CustomerSchema {
        // implementation for Customer schema
    }

    myDatasetClient1, _ := New[OrderEvent, OrderSchema](Parameters[OrderEvent, OrderSchema]{SchemaName: "schema1", TransformFn: orderTransformFn})
    myDatasetClient2, _ := New[CustomerEvent, CustomerSchema](Parameters[CustomerEvent, CustomerSchema]{SchemaName: "schema2", TransformFn: customerTransformFn})
    // ...
}

Transformer 函數類型現在使用兩個類型參數進行參數化:用於事件類型的 E 和用於架構類型的 S
參數和資料儲存結構也使用相同的兩個型別參數 ES 進行參數化。
DataStore 的transformEvent 方法現在接受類型為E 的事件並傳回類型為S 的模式。

要處理更多模式,您可以定義符合 Transformer 函數簽署的新函數類型或實例,以及對應的事件和模式結構。您不會定義實作 Transformer 介面的新結構,因為 Transformer 現在是函數類型,而不是介面。
因此,您可以透過定義新的 轉換函數和架構結構,無需修改現有的 DataStore 實作。

以上是重構一個期望一件事期望很多事情的對象的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除