php小编鱼仔在编程中,我们经常会遇到一个对象希望承担多个职责的情况。这种对象被称为"重构一个期望一件事期望很多事情的对象"。这样的对象通常会导致代码臃肿、耦合度高,难以维护和扩展。在这篇文章中,我们将探讨如何重构这样的对象,使其更加清晰、灵活和易于维护。让我们一起来看看吧!
我正在努力更新 Go 代码库。我们公司有一个中央数据存储,虚构地称为 DataStore,您可以将其发布到各种数据集或模式或从中读取。我们特定的代码库有一些代码将特定的数据集/模式耦合到 DataStore 实现。我需要重构此代码以能够写入其他(可能还有更多)数据集。
在下面的代码中,dataStoreSchema
表示单个架构,例如“Customers”数据。但我有其他模式,例如“订单”,或者任何具有我想要写入的不同字段的模式。
transformEvent
获取将传递到 transformEvent
获取将传递到 DataStore
的数据,并执行一些逻辑来创建 dataStoreSchema
的数据,并执行一些逻辑来创建
我想写入数据存储上的潜在任何
模式,而不仅仅是该实现所耦合的模式。
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})
dataStoreSchema
结构和 transformEvent
方法与特定模式紧密耦合。 transformEvent
方法接受输入并将其转换为 dataStoreSchema
如果我理解正确,您当前的实现通过
transformEvent
方法与特定模式紧密耦合。 transformEvent
方法接受输入并将其转换为 对象,然后将其写入 DataStore。
您可能希望写入数据存储上的任何模式,而不仅仅是当前实现所耦合的模式。DataStore
客户端,每个客户端与不同的 schema 和相应的转换函数相关联(transformEvent1
、transformEvent2
、transformEvent3
myDatasetClient1 := DataStore.New(params{schema1, transformEvent1}) myDatasetClient2 := DataStore.New(params{schema2, transformEvent2}) myDatasetClient3 := DataStore.New(params{schema3, transformEvent3})
DataStore
)。
这应该意味着将转换逻辑与 结构解耦,允许使用不同的转换函数处理不同的模式。Parameters
和 DataStore
Parameters
和 结构:E
和用于架构类型的 S
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: ¶ms}, 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}) // ... }
E
和 S
。E
的事件并返回类型为S
进行参数化。
DataStore 的transformEvent 方法现在接受类型为 的模式。Transformer
函数签名的新函数类型或实例,以及相应的事件和模式结构。您不会定义实现 Transformer
接口的新结构,因为 Transformer
要处理更多模式,您可以定义符合 现在是函数类型,而不是接口。
因此,您可以通过定义新的 DataStore
转换函数
以上是重构一个期望一件事期望很多事情的对象的详细内容。更多信息请关注PHP中文网其他相关文章!