.NET 快速重构概要2

1.封装条件

        当代码中充斥着若干条件判断时,代码的真正意图会迷失于这些条件判断之中。这时我喜欢将条件判断提 取到一个易于读取的属性或方法(如果有参数)中。重构之前的代码如下:

public class RemoteControl
{
    private string[] Functions { get; set; }
    private string Name { get; set; }
    private int CreatedYear { get; set; }

    public string PerformCoolFunction(string buttonPressed)
    {
        // Determine if we are controlling some extra function 
        // that requires special conditions 
        if (Functions.Length > 1 && Name == "RCA" &&
        CreatedYear > DateTime.Now.Year - 2)
            return "doSomething";
    }
}

重构之后,代码的可读性更强,意图更明显:

public class RemoteControl
{
    private string[] Functions { get; set; }
    private string Name { get; set; }
    private int CreatedYear { get; set; }

    private bool HasExtraFunctions
    {
        get
        {
            return Functions.Length > 1 && Name == "RCA" &&
            CreatedYear > DateTime.Now.Year - 2;
        }
    }

    public string PerformCoolFunction(string buttonPressed)
    {
        // Determine if we are controlling some extra function 
        // that requires special conditions 
        if (HasExtraFunctions)
            return "doSomething";
    }
}

 2.提取超类

当一个类有很多方法希望将它们“提拔”到基类以供同层次的其他类使用时,会经常使用该重构。下面的 类包含两个方法,我们希望提取这两个方法并允许其他类使用。

public class Dog
{
    public void EatFood()
    {
        // eat some food 
    }

    public void Groom()
    {
        // perform grooming 
    }
}

重构之后,我们仅仅将需要的方法转移到了一个新的基类中。这很类似“Pull Up”重构,只是在重构之前, 并不存在基类。

public class Animal
{
    public void EatFood()
    {
        // eat some food 
    }

    public void Groom()
    {
        // perform grooming 
    }
}
public class Dog : Animal
{
}

3.将异常替换为条件

我曾无数次面对的一个代码坏味道就是,使用异常来控制程序流程。您可能会看到类似的代码:

public class Microwave
{
    private IMicrowaveMotor Motor { get; set; }

    public bool Start(object food)
    {
        bool foodCooked = false;
        try
        {
            Motor.Cook(food);
            foodCooked = true;
        }
        catch (InUseException)
        {
            foodcooked = false;
        }

        return foodCooked;
    }
}

        异常应该仅仅完成自己的本职工作:处理异常行为。大多数情况你都可以将这些代码用恰当的条件判断替 换,并进行恰当的处理。下面的代码可以称之为契约式设计,因为我们在执行具体工作之前明确了 Motor 类的状态,而不是通过异常来进行处理。

public class Microwave
{
    private IMicrowaveMotor Motor { get; set; }

    public bool Start(object food)
    {
        if (Motor.IsInUse)
            return false;

        Motor.Cook(food);

        return true;
    }

}

4.提取工厂类

        在代码中,通常需要一些复杂的对象创建工作,以使这些对象达到一种可以使用的状态。通常情况下,这 种创建不过是新建对象实例,并以我们需要的方式进行工作。但是,有时候这种创建对象的需求会极具增 长,并且混淆了创建对象的原始代码。

        这时,工厂类就派上用场了。关于工厂模式更全面的描述可以参考 这里。最复杂的工厂模式是使用抽象工厂创建对象族。而我们只是使用最基本的方式,用一个工厂类创建 一个特殊类的实例。来看下面的代码:

public class PoliceCarController
{
    public PoliceCar New(int mileage, bool serviceRequired)
    {
        PoliceCar policeCar = new PoliceCar();
        policeCar.ServiceRequired = serviceRequired;
        policeCar.Mileage = mileage;

        return policeCar;
    }
}

        如您所见,New 方法负责创建 PoliceCar 并根据一些外部输入初始化 PoliceCar 的某些属性。对于简单的创建 工作来说,这样做可以从容应对。但是久而久之,创建的工作量越来越大,并且被附加在 controller 类上, 但这并不是 controller 类的职责。这时,我们可以将创建代码提取到一个 Factory 类中去,由该类负责 PoliceCar 实例的创建。

public interface IPoliceCarFactory
{
    PoliceCar Create(int mileage, bool serviceRequired);
}

public class PoliceCarFactory : IPoliceCarFactory
{
    public PoliceCar Create(int mileage, bool serviceRequired)
    {
        PoliceCar policeCar = new PoliceCar();
        policeCar.ReadForService = serviceRequired;
        policeCar.Mileage = mileage;
        return policeCar;
    }
}

public class PoliceCarController
{
    public IPoliceCarFactory PoliceCarFactory { get; set; }
    public PoliceCarController(IPoliceCarFactory policeCarFactory)
    {
        PoliceCarFactory = policeCarFactory;
    }

    public P
  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜飞鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值