官术网_书友最值得收藏!

Resistance to change

These are cases where it is difficult and/or slow to add new features. Similarly, tests are often harder to write, especially tests for failure conditions. Similar to code bloat, these smells can be the result of a gradual degradation and lack of maintenance, but they can also be caused by a lack of up-front planning or poor API design.

They can be found by examining the pull request log or commit history and, in particular, determining if new features require many small changes in different parts of the code. 
If your team tracks feature velocity and you notice it is declining, this is also a likely cause.

These smells include the following:

  • Shotgun surgery: This is when small changes made to one struct necessitate changes in other structs. These changes imply that the organisation or abstraction used was incorrect. Typically, all of these changes should be in one class.
    In the following example, you can see how adding an email field to the person data would result in changing all three structs (Presenter, Validator, and Saver):
// Renderer will render a person to the supplied writer
type Renderer struct{}

func (r Renderer) render(name, phone string, output io.Writer) {
// output the person
}

// Validator will validate the supplied person has all the
// required fields
type Validator struct{}

func (v Validator) validate(name, phone string) error {
// validate the person
return nil
}

// Saver will save the supplied person to the DB
type Saver struct{}

func (s *Saver) Save(db *sql.DB, name, phone string) {
// save the person to db
}
  • Leaking implementation details: One of the more popular idioms in the Go community is accept interfaces, return structs. It's a catchy turn of phrase, but its simplicity masks its cleverness. When a function accepts a struct, it ties the user to a particular implementation—a strict relationship that makes future changes or additional usage difficult. By extension, if that implementation detail were to change, the API changes and forces changes on its users.

Applying DI to these smells is typically a good investment in the future. While not fixing them is not fatal, the code will progressively degrade until you are dealing with the proverbial big ball of mud. You know the type—a package that no-one understands, no-one trusts, and only the brave or stupid are willing to make changes to. DI enables you to decouple from the implementation choices, thereby making it easier to refactor, test, and maintain small chunks of code in isolation.

主站蜘蛛池模板: 乌兰察布市| 南川市| 昂仁县| 瓮安县| 利辛县| 江永县| 邹城市| 开化县| 南充市| 五河县| 普宁市| 固镇县| 板桥市| 汉寿县| 辽中县| 巫溪县| 北流市| 芜湖市| 文登市| 贵溪市| 永和县| 延边| 海口市| 武义县| 谷城县| 灵武市| 聊城市| 樟树市| 石林| 潮安县| 宣武区| 横山县| 武隆县| 浦东新区| 澳门| 宁乡县| 云安县| 剑河县| 定远县| 车险| 伊宁市|