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

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.

主站蜘蛛池模板: 潍坊市| 黄梅县| 东台市| 永修县| 河北区| 武隆县| 遵化市| 疏附县| 北海市| 林甸县| 陆丰市| 沁源县| 随州市| 峨山| 眉山市| 舟山市| 麟游县| 休宁县| 咸阳市| 南康市| 汕头市| 朝阳市| 疏勒县| 吉林市| 逊克县| 满洲里市| 开封市| 平顶山市| 淅川县| 奉新县| 宾阳县| 梁山县| 临海市| 平定县| 新和县| 澄江县| 黎城县| 博野县| 民勤县| 黄梅县| 扶余县|