改善代码设计 “.NET研究”—— 处理概括关系(Dealing with Generalization)

简介:   系列博客      1. 改善代码设计 —— 优化函数的构成(Composing Methods)      2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)      3.

  系列博客

      1. 改善代码设计 —— 优化函数的构成(Composing Methods)

      2. 改善代码设计 —— 优化物件之间的特性(Moving Features Between Objects)

      3. 改善代码设计 —— 组织好你的数据(Composing Data)

      4. 改善代码设计 —— 简化条件表达式(Simplifying Conditional Expressions)

      5. 改善代码设计 —&mdas上海企业网站设计与制作h; 简化函数调用(Making Method Calls Simpler)

      6. 改善代码设计 —— 处理概括关系(Dealing with Generalization)

  1. Pull Up Field (提升值域)

  解释:

      如果发现每个子类都拥有相同的某个值域, 那么使用 Pull Up Field 将这个值域提升到父类中去.

  冲动前:

  冲动后:

  2. Pull Up Method (提升函数)

  解释:

      如果每个子类都有相同的某个函数, 这个函数做同样的事情, 而且结果也相同, 那么使用 Pull Up Method 将这个函数提升到父类中去.

  冲动前:

  冲动后:

  3. Pull Up Constructor Body (提升构造函数)

  解释:

      特别要注意每个子类中重复的代码, 如果可能的话尽量将它们提炼成方法并搬到父类中去. 对于子类的构造函数, 我们需要找出相同的部分, 用这些相同的部分组成父类的构造函数.

      如下面的例子, 如果不光 Salesman, 还有 Engineer 等等类别的员工在构造他们的时候都需要 name 和 level 属性, 可以考虑使用 Pull Up Constructor Body 将设置这两个属性提升到父类的构造函数中去.

  冲动前:

 
 
class Employee
{
public string Name { get ; set ; }
public int Level { get ; set ; }
// ...
}
class Salesman : Employee
{
public string Hobby { get ; set ; }

public Salesman( string name, int 上海徐汇企业网站设计与制作="color: #000000;"> level, string hobby)
{
this .Name = name;
this .Level = level;
this .Hobby = hobby;
}
// ...
}
// ...

  冲动后:

 
 
class Employee
{
public string Name { get ; set ; }
public int Level { get ; set ; }

public Employee( string name, int level)
{
this .Name = name;
this .Level = level;
}
// ...
}
class Salesman : Employee
{
public string Hobby { get ; set ; }

public Salesman( string name, int level, string hobby): base (name,level)
{
this .Hobby = hobby;
}
// ...
}
// ...

  4. Push Down Method (降低函数)

  解释:

      父类里有某个函数只与一部分子类有关, 并不是与所有的子类都有关, 使用 Push Down Method 重构手段将这些函数放到使用它们的子类中去, 而不要放到父类中.

  冲动前:

  冲动后:

  5. Push Down Field (降低值域)

  解释:

      与 Push Down Method 描述的问题类似, 父类中如果某个值域并不是对于每个子类都有用的, 应该把它放到需要它的子类中去.

  6. Extract Subclass (提炼子类)

  解释:

      我们产生了类的一些实例, 但并不是每个实例都用得到类中所有的特性, 往往这是类中功能设计过多的原因造成的. 尝试从这个类中提炼出一些子类, 子类中的功能应该划分得很明确.

  7. Extract Superclass (提炼父类)

  解释:

      如果你发现有两个类, 他们有很多相同的特性, 尝试找出两个类中相同的特性, 如果你能找到一个合适的理由让这两个类继承自一个父类, 从而你可以提炼出这个父类, 父类中包含那两个类中相同的部分.

  8. Extract Interface (提炼接口)

  解释:

      类与类之间经常会相互调用, 比如 ClassA 的某个函数里需要 ClassB 里的某个值域或者某个函数的返回值, 因此我将整个 ClassB 作为参数传递给 ClassA 的这个函数, 这意味着 ClassA 的这个函数能够调用 ClassB 里所有的功能, 可不可以给 ClassA 的这个函数划定一个特定的职能呢? 让它只能做某些事情, 而避免其它 "越权行为". 有句话常被人说起 —— 使用接口来降低耦合性, 这就是 Extract Interface 的功劳.

      这条重构手段经常被使用到, 主要解决类对另一个类的依赖问题, 降低了耦合性.

  冲动前:

 
 
class Xml
{
public void Read()
{
// ...
}
public void Translate()
{
// ...
}
// some other methods
}
class WeatherService
{
public string GetWeather(Xml xml)
{
xml.Read();
xml.Translate();
// other code, but without xml object
}
// some other methods
}

  冲动后:

 
 
interface IOperation
{
void Read();
void Translate();
}
class Xml : IOperation
{
public void Read()
{
// ...
}
public void Translate()
{
// ...
}
// some other methods
}
class WeatherService
{
public string GetWeather(IOperation operation)
{
operation.Read();
operation.Translate();
// other code, but without xml object
}
// some other methods
}

      注意代码高亮的那行已经变成调用接口, 而不是仅依赖调用 Xml 类的实例, 对于单个类实现这样的接口并不是很有价值, 如果很多类都实现了同样的接口, 这将是很有用的事情.

  9. Collapse Hierarchy (去掉不必要的继承关系)

  解释:

      庞大的继承体系很容易变得复杂, 理清父类与子类它们各自的职能是非常重要的, 你很有可能会发现不必要的子类, 那么使用 Pull Up Field 和 Pull Up Method 将它干掉.

  10. Replace Inheritance with Delegation (用委派取代继承)

  解释:

      如果你想让 ClassA 使用某个类 (如 ClassB) 的某个函数, 就让 ClassA 继承自 ClassB, 这将是一个多么糟糕的设计! 你可以在 ClassA 中包含一个 ClassB 的值域, 通过这个值域调用你需要的函数, 这个值域就是"委派", 而你这时可以去掉 ClassA 和 ClassB 之间不该存在的继承关系了.

  11. Replace Delegation with Inheritance (用继承代替委派)

  解释:

      这一条与 Replace Inheritance with Delegation 正好相反, 如果你需要使用委派中的所有函数, 这时你就应该想想它们之间是不是存在继承关系.

目录
相关文章
|
4月前
分享一份 .NET Core 简单的自带日志系统配置,平时做一些测试或个人代码研究,用它就可以了
分享一份 .NET Core 简单的自带日志系统配置,平时做一些测试或个人代码研究,用它就可以了
|
6月前
|
机器学习/深度学习 JSON 测试技术
CNN依旧能战:nnU-Net团队新研究揭示医学图像分割的验证误区,设定先进的验证标准与基线模型
在3D医学图像分割领域,尽管出现了多种新架构和方法,但大多未能超越2018年nnU-Net基准。研究发现,许多新方法的优越性未经严格验证,揭示了验证方法的不严谨性。作者通过系统基准测试评估了CNN、Transformer和Mamba等方法,强调了配置和硬件资源的重要性,并更新了nnU-Net基线以适应不同条件。论文呼吁加强科学验证,以确保真实性能提升。通过nnU-Net的变体和新方法的比较,显示经典CNN方法在某些情况下仍优于理论上的先进方法。研究提供了新的标准化基线模型,以促进更严谨的性能评估。
177 0
|
7月前
|
机器学习/深度学习 算法 数据可视化
MATLAB基于深度学习U-net神经网络模型的能谱CT的基物质分解技术研究
MATLAB基于深度学习U-net神经网络模型的能谱CT的基物质分解技术研究
|
机器学习/深度学习 数据采集 存储
【3-D深度学习:肺肿瘤分割】创建和训练 V-Net 神经网络,并从 3D 医学图像中对肺肿瘤进行语义分割研究(Matlab代码实现)
【3-D深度学习:肺肿瘤分割】创建和训练 V-Net 神经网络,并从 3D 医学图像中对肺肿瘤进行语义分割研究(Matlab代码实现)
274 0
|
弹性计算 NoSQL Linux
.Net Core实战之基于角色的访问控制的设计-部署篇
2年前开源了Sikiro.RBAC系统(https://github.com/SkyChenSky/Sikiro.RBAC)但是缺少了部署流程,这次通过申请免费的ECS,重新把流程梳理了下,并整理成改篇文章。 .Net Core实战之基于角色的访问控制的设计(https://www.cnblogs.com/skychen1218/p/13053878.html)
80536 23
.Net Core实战之基于角色的访问控制的设计-部署篇
|
安全 搜索推荐 数据安全/隐私保护
用.NET设计一个假装黑客的屏幕保护程序
本文主要介绍屏幕保护程序的一些相关知识,以及其在安全方面的用途,同时介绍了如何使用 .NET 开发一款屏幕保护程序,并对核心功能做了介绍,案例代码开源:https://github.com/sangyuxiaowu/HackerScreenSaver
190 0
用.NET设计一个假装黑客的屏幕保护程序
|
数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计(二)
.Net Core实战之基于角色的访问控制的设计(二)
162 0
.Net Core实战之基于角色的访问控制的设计(二)
|
数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计(三)
.Net Core实战之基于角色的访问控制的设计(三)
167 0
.Net Core实战之基于角色的访问控制的设计(三)
|
SQL NoSQL 前端开发
.Net Core实战之基于角色的访问控制的设计(一)
.Net Core实战之基于角色的访问控制的设计(一)
241 0
.Net Core实战之基于角色的访问控制的设计(一)
|
弹性计算 数据安全/隐私保护
.Net Core实战之基于角色的访问控制的设计-
2年前开源了Sikiro.RBAC系统(https://github.com/SkyChenSky/Sikiro.RBAC)但是缺少了部署流程,这次通过申请免费的ECS,重新把流程梳理了下,并整理成改篇文章。 .Net Core实战之基于角色的访问控制的设计(https://www.cnblogs.com/skychen1218/p/13053878.html)