模式学习---策略模式

原创 2018年04月15日 16:14:45

有这么一个鸭子类Duck,包含方法display,swim,fly,quack,其中display,swim方法是不会变的,而fly,quack将来可能会变化,根据”封装变化“的原则,将fly,quack设计成接口。

 public interface IFlyable
    {
        void Fly();
    }
 public interface IQuackable
    {
        void Quack();
    }

实现这二个接口的具体类,分别实现其功能,类Quack实现呱呱叫功能,Squeak实现吱吱叫功能。

 class Quack : IQuackable
    {
        void IQuackable.Quack()
        {
            Console.WriteLine("呱呱呱");
        }
    }
class Squeak : IQuackable
    {
        public void Quack()
        {
            Console.WriteLine("吱吱吱");
        }
    }

 class FlyNoWay : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("飞不起来");
        }
    }
 class FlyWithWings : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("展开翅膀,飞呀飞");
        }
    }
class FlyRocketPowered : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("带火箭动力装置向前狂飞........");
        }
    }


FlyNoWay实现不能飞的功能,FlywithWings实现带翅膀飞的功能,FlyRocketPowered实现带火箭推动装置的功能。
鸭子设计成抽象类

 public abstract class Duck
    {        
        protected IFlyable flyBehavior;
        protected IQuackable quackBehavior;

        public abstract string Name { get; set; }
        public void Swim()
        {
            Console.WriteLine("游啊游...");
        }

        public void Display()
        {
            Console.WriteLine($"{Name}");
        }

        public void PerformFly()
        {
            flyBehavior.Fly();
        }

        public void PerformQuack()
        {
            quackBehavior.Quack();
        }

        public void SetFlyBehavior(IFlyable fb)
        {
            flyBehavior = fb;
        }

        public void SetQuackBehavior(IQuackable qb)
        {
            quackBehavior = qb;
        }
    }
所有的鸭子都从这个鸭子抽象类继承,绿头鸭
public class MallardDuck : Duck
    {
        private string name;

        
       public MallardDuck()
        {
            Name = "绿头鸭";
            flyBehavior = new FlyWithWings();
            quackBehavior = new Quack();
        }

        public override string Name { get => name; set => name = value; }
    }
模型鸭也从这个抽象类继承
 public class ModelDuck:Duck
    {
        private string name;
        public ModelDuck()
        {
            Name = "模型鸭";
            flyBehavior = new FlyNoWay();
            quackBehavior = new Quack();
        }

        public override string Name { get =>name; set => name=value; }
    }
我们来运行一下看看,在运行时更换一下行为看怎么样?
 static void Main(string[] args)
        {
            Duck mallard = new MallardDuck();
            mallard.Display();
            mallard.Swim();
            mallard.PerformFly();
            mallard.PerformQuack();
            Console.WriteLine("=====================>");
            Duck model = new ModelDuck();
            model.Display();
            model.Swim();
            model.PerformFly();
            model.PerformQuack();

            Console.WriteLine("改变模型鸭的飞行行为==========>");
            model.SetFlyBehavior(new FlyRocketPowered());
            model.PerformFly();

            Console.WriteLine("运行结束======================>");

            Console.ReadLine();
        }

运行效果

设计原则:
  1. 多用组合,少用继承。
  2. 面向接口设计,不要面向实现设计。
  3. 对修改关闭,对扩展开放。
针对这一原则 ,再设计一个角色类,这个类有一个武器是可以在运行时更换,一个fight战斗方法。

显然武器要设计成一个接口

public interface IWeaponable
    {
        string UseWeapon();
    }
角色类Character
 public abstract class Character
    {
        protected IWeaponable weapon;

        public abstract void Fight();

        public void SetWeapon(IWeaponable wb)
        {
            weapon = wb;
        }
    }
从接口武器生成这么几个类,小刀knife,剑sword,斧子Axe和弓箭BowAndArrow
class Knife : IWeaponable
    {
        public string UseWeapon()
        {
            return "使用小刀攻击";
        }
    }
 class Sword : IWeaponable
    {
        public string UseWeapon()
        {
            return "挥舞着剑攻击";
        }
    }
 class Axe : IWeaponable
    {
        public string UseWeapon()
        {
            return "挥舞着斧头劈砍";
        }
    }
class BowandArrow : IWeaponable
    {
        public string UseWeapon()
        {
            return "运用弓箭射出箭矢";
        }
    }



从角色类继承的有这么几个类,武士Knight,国王King,王后Queen
  class Knight : Character
    {
        public Knight()
        {
            weapon = new Axe();
        }
        public override void Fight()
        {
            Console.WriteLine($"武士 {weapon.UseWeapon()} 战斗");
        }
    }
 class Queen : Character
    {
        public Queen()
        {
            weapon = new BowandArrow();
        }
        public override void Fight()
        {
            Console.WriteLine($"王后 {weapon.UseWeapon()} 战斗");
        }
    }
 class King:Character
    {
        public King()
        {
            weapon = new Sword();
        }

        public override void Fight()
        {
            Console.WriteLine($"国王 {weapon.UseWeapon()} 战斗");
        }
    }
运行一下看看
static void Main(string[] args)
        {
            Character knight = new Knight();
            knight.Fight();
            Character king = new King();
            king.Fight();
            Character queen = new Queen();
            queen.Fight();
            king.SetWeapon(new Knife());
            king.Fight();
            Console.WriteLine("========================");
            Console.ReadLine();
        }

效果


运行得不错,可以更换武器。

设计模式--深度解析策略模式(Strategy Pattern)

前些天网购一本Head First Design Patterns,学习了一下,觉得写的挺好,而且挺有趣的,推荐大家都去买一本,真心不错。在这里我先讲一下,这两天学的,两个常见的设计模式,分别Stra...
  • qq_29282475
  • qq_29282475
  • 2015-12-04 14:17:25
  • 4293

《JAVA与模式》之策略模式——我看过最好的一篇策略模式博文

《JAVA与模式》之策略模式(转载自http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html) 在阎宏博士的《JAV...
  • zhangliangzi
  • zhangliangzi
  • 2016-08-09 11:30:33
  • 12954

策略模式(Strategy)和委托(Delegate)的比较

Strategy模式是对算法的封装。即使是一个计算行为,如果其实现有其多样性,为达到易扩展的目的,我们可以将其抽象出来,以接口的形式来定义。利用了面向对象的多态性,在运行时,可以灵活的变更这个算法的具...
  • ycyangcai
  • ycyangcai
  • 2011-06-27 22:33:00
  • 5823

模板方法模式与策略模式的区别

原文:http://www.tuicool.com/articles/6JBN7z3 一、主要思想和意图的区别 如果你还不了解模板方法模式和策略模式,请先阅读《  策略模式(strategy) 》和...
  • hudashi
  • hudashi
  • 2016-03-25 13:57:06
  • 3857

设计模式之桥梁模式和策略模式的区别

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式。以下是它们的UML结构图。 桥梁模式: 策略模式: 在桥接模式中,Abstraction通过聚合的...
  • xingjiarong
  • xingjiarong
  • 2015-12-16 21:57:53
  • 2778

Design Pattern: 策略模式和适配器模式

策略模式用于抽象对于同一个对象的不同处理方式,把相同处理方式(内部状态)抽象成一个类,通过策略选择类选择产生对应的策略来处理输入的对象。 换个角度想想,其实策略模式需要结合简单工厂模式一起使用,是...
  • Firehotest
  • Firehotest
  • 2016-10-02 10:12:02
  • 1237

我所理解的设计模式(C++实现)——策略模式(Strategy Pattern)

每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。 而策略模式就是对算法进行包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通...
  • LCL_data
  • LCL_data
  • 2013-08-24 10:59:44
  • 13278

设计模式之策略模式(python实现)

最近在读《深入浅出设计模式》这一本书,收获颇多,打算写一个系列的blog,并用python实现其中的每一个设计模式,以加深理解。              下面将要介绍的就是书中的第一个设计模式...
  • huangkangying
  • huangkangying
  • 2012-08-10 23:19:57
  • 5043

大话设计模式—策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。大话设计模式中程杰老师给出的定义是这样的:策略模式(Strategy),定义了...
  • lmb55
  • lmb55
  • 2016-03-23 23:59:47
  • 2140

Unity设计模式之策略模式的使用

策略模式和之前讲的简单工厂模式很相似,都是利用多态的性质,其中的区别仔细观察可以归纳为:1、简单工厂模式:传条件进工厂类,工厂类就会返回一个创建的对象给调用者使用。2、策略模式:传一个要使用的策略实例...
  • SaveWord
  • SaveWord
  • 2015-05-23 22:07:44
  • 683
收藏助手
不良信息举报
您举报文章:模式学习---策略模式
举报原因:
原因补充:

(最多只允许输入30个字)