C# 去除if-else以及子类管理 (上)策略模式+工厂模式

这是我的第一篇技术博客,虽说技术点不多,但是练习写下来也多多少少是个收获,这里我会根据我遇到的问题和我使用的解决方法一点一点进行代码更改。废话不多少直接进入正题。

一般在编码过程当中,我们需要通过一个条件进行筛选某一子类的时候,需要用到大量的if else或者Swich,本文章将在一点点的解决这些问题,在需要新的需求的时候,直接添加子类便可实现相关功能。

我们都知道,处理一个问题的时候,使用策略模式可以达到多样化的处理,并且可以在不修改原有Context的情况下进行实现。

举个例子,某游戏中的Vip机制,在一定金钱下的消费是普通会员,没有折扣。当消费到一定程度的时候,这里我们假设为1000金的时候,升级为初级会员,可以享受九折折扣,这里我们直接使用策略模式进行编写代码:

会员基类:IVipStrategy,根据当前消费price计算当前会员制度的折扣价格。

public interface IVipStrategy
{
    float GetExtenditure(float price);
}

消费等级的子类,大众会员PublicVipStrategy, 初级会员 JuniorVipStrategy。

public class PublicVipStrategy : IVipStrategy
{
    public float GetExtenditure(float price)
    {
        return price;
    }
}

public class JuniorVipStrategy : IVipStrategy
{
    public float GetExtenditure(float price)
    {
        return price * 0.9f;
    }
}

上下文环境我们使用消费者PlayerContext

using System;

public class Consumer
{
    private float _price;
    private float _totalConsume;
    private IVipStrategy _vipStrategy;

    public Consumer()
    {
        _vipStrategy = new PublicVipStrategy();
    }
    public void Buy(int price)
    {
        _price = GetConsume(price);
        Console.WriteLine("消费了 : " + _price);
        _totalConsume += _price;
    }
    private float GetConsume(int price)
    {
        if ((0 <= _totalConsume) && (_totalConsume < 1000))
            _vipStrategy = new PublicVipStrategy();
        else if ((1000 <= _totalConsume) && (_totalConsume < 2000))
            _vipStrategy = new JuniorVipStrategy();
        return _vipStrategy.GetExtenditure(price);
    }
}

然后我们在主函数中调用测试一下

public class ContextView
{
    public void Main()
    {
        Consumer consumer = new Consumer();
        consumer.Buy(1000);
        consumer.Buy(1000);
    }
}

输出结果:

  

这里我们就可以看到两次购买价值1000金的商品,第一次由于是大众会员不享受折扣优惠,则直接全价购买。购买完毕之后达到了下一等级Vip要求,然后第二次购买的时候则享受9折优惠。接下来我们加入工厂模式将Cosumer中的策略选择提取出来。

public class VipStrategyFactory
{
    private static VipStrategyFactory _instance;

    public static VipStrategyFactory Instance
    {
        get
        {
            if (_instance == null)
                _instance = new VipStrategyFactory();
            return _instance;
        }
    }

    public IVipStrategy GetVipStrategy(Consumer consumer)
    {
        float totalConsume = consumer.TotalConsume;
        if ((0 <= totalConsume) && (totalConsume < 1000))
            return new PublicVipStrategy();
        if ((1000 <= totalConsume) && (totalConsume < 2000))
            return new JuniorVipStrategy();
        return new PublicVipStrategy();
    }
}

改写下消费者类

using UnityEngine;

public class Consumer
{
    private float _price;
    public float TotalConsume { private set; get;  }//修改为属性
    private IVipStrategy _vipStrategy;

    public Consumer()
    {
        _vipStrategy = new PublicVipStrategy();
    }

    public void Buy(int price)
    {
        _price = GetConsume(price);
        Debug.Log("消费了 : " + _price);
        TotalConsume += _price;
    }

    private float GetConsume(int price)
    {
        //由工厂选择策略
        _vipStrategy = VipStrategyFactory.Instance.GetVipStrategy(this);
        return _vipStrategy.GetExtenditure(price);
    }
}

通过工厂我们可以看得到这里我们仍然需要使用到if else进行策略选择,当我们添加新的会员政策的时候,需要编写子类,同时需要修改工厂添加新的条件,在下一篇我们引入C#特性的概念给每一个会员添加自己的消费范围。

转载请标明出处。

你可能感兴趣的:(技术文档)