前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式之策略模式(Strategy)

设计模式之策略模式(Strategy)

作者头像
阿新
发布2018-04-13 10:10:58
7560
发布2018-04-13 10:10:58
举报
文章被收录于专栏:c#开发者c#开发者

策略模式:

策略模式属于对象行为模式[GOF95]。其用意是针对一组算法,将每一个算法封装到具体共同缄口的独立的类中,从来是的他们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化

问题

    架设现在要设计一个贩卖各类书籍的电子商务网站的购物车(shopping cart)系统。一个简单的情就是把所有货品的单价乘上数量,但是实际情况肯定比这复杂,比如对不同的图书给与折扣的问题

解决方案

    1/把所有的业务逻辑都放在客户端里面。客户端利用条件选择语句决定使用哪一个算法。这样一来,客户端代码会变得复杂难以维护。

    2/客户端可以利用继承的办法在子类里面实现不同的行为,但是这样会使得环紧和行为紧密耦合在一起,使得两者不能单独演化。

    3/使用策略模式。策略模式把行为和环境分割开来。环境负责维持和查询行为类,各类算法则在具体的策略类(ConcreteStrategy)中提供。由于算法和环境独立开来,算法的增减,修改都不会影响环境和客户端。

    策略模式正是解决这个问题的系统化方法。当出现新的折扣或现有的折扣出现变化,只需要实现新的策略类,并在客户端登记即可。策略模式相当于“可插入式(Pluggable)的算法”。

    当准备在一个系统里使用策略模式时,首先必须找到需要包装的算法,看看算法是否可以从环境中分割开来,最后在考虑这些算法是否会在以后发生变化。

引进策略模式

    策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得他们可以互换。”

代码语言:javascript
复制
//环境类的源代码
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public class Context
    {
        private Strategy strategy;
    
        public void contextInterface()
        {
            strategy.strategyInterface();
        }
    }
}

//抽象策略类的源代码
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public abstract class Strategy
    {
        public abstract void strategyInterface();
    }
}
//具体策略类的源代码
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public class ConcreteStrategy : Strategy
    {
        public override void strategyInterface()
        {
            throw new Exception("The method or operation is not implemented.");
        }
    }
}

策略模式的实现有以下注意的地方 1/经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用java抽象类实现,而不能使用java接口 2/策略模式在每一个时刻都只能使用一个策略对象,但是有时候一个应用程序同时与几个策略对象相联系。换言之,在应用程序启动时,所有的策略对象就已经被创立出来,而应用程序可以在几个策略对象之间调换。

图书折扣的计算

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public abstract class DiscountStrategy
    {
        private float price;
        private int copies;

        public DiscountStrategy(float price, int copies)
        {
            this.price = price;
            this.copies = copies;

        }
    
        public abstract double calclateDiscount();

    }
}



using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public class FlatTateStrategy : DiscountStrategy
    {
        private float price;
        private int copies;
        private float acmount;
        public FlatTateStrategy(float price, int copies)
        {
            this.price = price;
            this.copies = copies;
        }

        public float Amount
        {
            get
            {
                return this.acmount;
            }
            set
            {
                this.acmount = value;
            }
        }
    
        public override double calclateDiscount()
        {
            return copies * acmount;
        }
    }
}



using System;
using System.Collections.Generic;
using System.Text;

namespace StrategyPattern
{
    public class PercenttageStrategy : DiscountStrategy
    {
        private float percent;
        private float price;
        private int copies;

        public PercenttageStrategy(float price, int copies)
        {
            this.price = price;
            this.copies = copies;
        }

        public float Percent
        {
            get
            {
                return this.percent;
            }
            set
            {
                this.percent = value;
            }
        }
    
        public override double calclateDiscount()
        {
            return copies * price * percent;
        }
    }
}

在什么情况下应当使用策略模式 1/如果在一个系统里面有许多类,他们之间的却别仅在于他们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一中行为。 2/一个系统需要动态的在几种算法中选择一种。那么这些算法可以包装到一个个的具体算法类里面,而这些具体算法类都是一个抽象算法类的子类。换言之,这些具体算法类均有统一的接口,由于多太性原则,客户端可以选择用任何一个具体算法类,并持有一个数据类型的抽象算法类的对象。 3/一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复杂的和算法有关的数据。 4/如果一个对象有很多行为,如果不用适当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重条件选择语句,并体现面向对象设计的概念

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2006-06-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档