zoukankan      html  css  js  c++  java
  • 从△走进OO,走进策略模式

    现实中很多设备要根据某些数值来计算出其他值,如已知园的半径求其面积、已知三角形三边求其周长等等还有一些工艺设备也会用到此类方法,归根到底就是应用一个公式来算出相应的属性值。现在以三角形为例来学习此类问题的解决方法。

      基本需求:根据三边a、b、c求三角形周长。

      基本抽象:一个三角形类Triangle,有一个求周长的方法GetCirByABC(); 

      基本实现:

    public class Triangle
    {
        public double GetCirByABC(double a, double b, double c)
        {
            return a + b + c;
        }

    }

    基本不足:依照OO的抽象不应依赖细节,显然a、b、c以及返回值都定位到相应的属性了,违背了抽象不依赖细节原则,故应直接返回一个Triangle对象,他的好处之一就是需要什么值就通过属性来取相应的值,好处之二后面会提到。

    改进后的实现:

    public class Triangle
    {
        
    public double A { getset; }
        
    public double B { getset; }
        
    public double C { getset; }
        
    public double Cir { getset; }

        
    public Triangle GetModel(Triangle tg)
        {
            tg.Cir 
    = tg.A + tg.B + tg.C;
            
    return tg;
        }

    }

     扩展需求:根据A和B边以及Cir周长求C边长度,看似直接增加一个方法即可解决。

    public Triangle GetModel(Triangle tg)
    {
        tg.C 
    = tg.Cir - tg.A - tg.B;
        
    return tg;
    }

    可以观察到直接返回对象的好处二,不变的是抽象,只是算法发生了变化,由此策略模式应运而生。

    策略模式(Strategy):他定义了一系列的算法,并将每一种算法封装起来,并且可以相互替换,新的算法诞生不会造成类结构的破坏,只是一种扩展而已。

    策略抽象类定义:

    abstract class Strategy
    {
        
    public abstract Triangle GetModel(Triangle tg);
    }

    2个具体策略类定义CirByABCStrategy和CByCirABStrategy:

    //根据周长和AB边求C
    class CByCirABStrategy:Strategy
    {
        
    public override Triangle GetModel(Triangle tg)
        {
            tg.C 
    = tg.Cir - tg.A - tg.B;
            
    return tg;
        }
    }
    //根据ABC求周长
    class CirByABCStrategy:Strategy
    {
        
    public override Triangle GetModel(Triangle tg)
        {
            tg.Cir 
    = tg.A + tg.B + tg.C;
            
    return tg;
        }
    }

    上下文类Context(保存一个策略类的引用)定义:

    class Context
    {
        
    private Strategy strategy;
        
    public Context(Strategy strategy)
        {
            
    this.strategy = strategy;
        }
        
    public Triangle ContextInface(Triangle tg)
        {
            
    return strategy.GetModel(tg);
        }
    }

    客户端求周长调用例子:

    Triangle triangle = new Triangle();
    triangle.A 
    = 3;
    triangle.B 
    = 4;
    triangle.C 
    = 5;
    Context context 
    = new Context(new CirByABCStrategy());//这里决定调用具体的策略类,如果是根据AB和Cir来求则为new CByCirABStrategy();
    Triangle tg 
    = context.ContextInface(triangle);
    Console.WriteLine(
    "策略模式求周长:" + tg.Cir);


    策略模式缺点:实施起来较复杂,如有N种设备,每种设备都存在这样的多种算法情况,可能某些设备存在三四种算法,那类的数量将是很大的。没有完美的设计只有适合的设计。

  • 相关阅读:
    【dp】船
    【dp】PKU 1952 buy low,buy lower
    【dp】合唱队形
    【dp】导弹拦截
    【dfs】POJ1321 棋盘问题
    工程师工作与学习的模式
    如何进行大规模在线数据迁移(来自Stripe公司的经验)
    Laravel事件监听器listener与事件订阅者Subscriber的区别
    微信小程序时间处理问题
    [翻译] Facebook HHVM 团队封闭开发三周成果展
  • 原文地址:https://www.cnblogs.com/tianlong/p/1779351.html
Copyright © 2011-2022 走看看