有这么一个鸭子类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();
}
运行效果
设计原则:
多用组合,少用继承。
面向接口设计,不要面向实现设计。
对修改关闭,对扩展开放。
针对这一原则 ,再设计一个角色类,这个类有一个武器是可以在运行时更换,一个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();
}
效果
运行得不错,可以更换武器。