手机版

设计指南——一个由鸭子游戏触发的设计理念(多态、继承、抽象、界面、战略家模式)

时间:2021-10-05 来源:互联网 编辑:宝哥软件园 浏览:

这篇博文是从现实生活中提炼出来的设计理念。现在是骨架。现在我就举代码例子来完成程序的血肉,让大家生动体验设计的精髓。自从我们学习了面向对象编程,它促进了我们的思维模式。一个事物所具有的东西,是被加上了相应的属性和方法的。()没有什么难的,但你学到的是最基本的语法,是一门你甚至都不太懂的语言。有了C语言程序,就可以轻松地把它改成C#、JAVA等。什么事这么难?大部分程序员扭曲了C#语言,把C的语法移植到C#上(不知道C#的时候,自己做的)。错了不可怕,可怕的是我拒绝改变。语言是一种工具,学习之后可以理解,但不同的设计思路决定了语言的本质区别。言归正传,一步一步分析一个简单的鸭子游戏程序。

首先,设计一个鸭子对象,对吗?大致:复制的代码如下:公开课Duck {void呱呱(){//.鸭子可以叫} void swim(){ //.会游泳} void Display() {//.外观}}然后鸭子游戏里有各种鸭子一边游泳一边在水里玩,各种鸭子都继承了鸭子类。

这是标准的OO(面向对象)技术吗?游戏运行良好.目前鸭子会叫会游,都在水里。有多无聊?让我们创新:

丑小鸭能飞向天空吗?O(_)o现在想让鸭子飞,所以需要给鸭子添加一个飞行方法,就像这样:复制代码如下:公开课duck {void呱呱(){//.鸭子会叫} void swim(){ //.将游泳} void Display() {//。现在,问题刚刚出现:演示节目的时候,“橡皮鸭”在屏幕上飞来飞去,游戏里有各种各样的鸭子。当没有Fly()的时候,小鸭子可以平稳地奔跑。将Fyl()添加到父类会导致所有子类都有Fly(),甚至那些不应该有它的子类也不能被豁免。因此,对代码进行的本地修改不仅会影响本地级别。看这张图,可能和你的想法不谋而合:

掩盖“橡皮鸭”的飞行模式。这是个不错的选择,让“橡皮鸭”不会飞来飞去~ ~(注意“橡皮鸭”会叫——“吱吱”)。现在游戏中又增加了一种鸭子~问题又来了~ ~现在加入的成员是——“DecoyDuck”,是木头做的假鸭子。它不会飞,肯定不会叫~好的。现在,对于这个新成员,只需这样做:

继续掩护它,它只能老老实实在水里游!你认为这项乏味的工作什么时候结束?鸭子的种类是无限的,你的噩梦也是无限的~继承这个解决方案,似乎决断力不行。你需要改变它。你觉得这个设计怎么样:我定义了一些接口。目前我做两个,一个Flyable,一个quackable:

Duck类也有改动,只包含两个方法:Swim(),display () :

然后,当不同的子类继承Duck类时,分别实现Fly()和Quack(),还使用了接口。你怎么想呢?看似有用,但从另一个角度看,子类继承的Fly()和Quack()都是重复代码。但是,重复代码是可以接受的。但是,如果在维护过程中有30个Duck子类,应该稍微修改一下Fly()。你是否觉得可维护性瞬间低到下限?在这种新的设计方法中,虽然解决了一些问题,但是代码不能重用!你感觉到了吗?还有更可怕的东西,飞鸭。飞行动作不一样。当你翻转360度时,你打算做什么?O(_)o无论你在哪里工作,使用什么编程语言,软件开发中始终伴随你的不变的真理是什么?(把你想到的答案写在评论里,期待你的回答。)清除所有以前的设计.现在我们知道使用继承并不能很好地解决问题,因为鸭子的行为在子类中是不断变化的,那些子类拥有这些行为是不合适的。flybable和Quackable的界面似乎不错,解决了这个问题(只有飞鸭继承flybable)。但是这仍然使您有很多任务要做,并且您仍然不能重用代码。当你在维护它的时候,你仍然需要一个接一个地遵循和修改相应的行为。对于这个问题,有一个设计原则可以解决这个问题。它可以实现代码重用,并可以添加和修改,使系统更加灵活。设计原则:找出应用程序中可能发生的变化,把它们分开,不要和不需要改变的代码混在一起。这是一些理论知识。为了骨架,我要丰满它的翅膀。继续看,你会有收获的!现在,是时候拿出鸭子课的变化部分了!目前可变的部分是苍蝇和呱呱,会变的。现在,将这两个行为从Duck类中分离出来,并创建一个新的类来表示每个行为。先做一个飞行行为的接口:公共接口fly behavior { void fly();}啜饮行为的界面:公共界面呱呱行为{void呱呱();你听说过这样的设计思想吗:为接口编程,而不是为实现编程?而“为接口编程”真正的意思是“为抽象类编程”。“为接口编程”的关键是多态性。利用多态性,程序可以针对抽象类进行编程,执行时会根据实际情况执行真实的行为,不会被抽象类的行为所束缚。再深一点,“为抽象类编程”这句话可以更清楚地表述为“变量的声明类型应该是抽象类型,可以是抽象类,也可以是接口”!不懂也没关系!接下来,我们用程序让大家慢慢了解这个概念!举个传统的例子:为实现编程:Dog d=new Dog();d . bark();//“汪汪”表示行为针对接口或抽象类编程:Animal Animal=new Dog();animal . MakeSound();//这个方法实现“汪汪”,所以我不懂?不要紧,有图:

现在让我们在鸭子游戏中重新实现这个设计!先设计飞行行为:复制代码如下:级fly with wings : fly behavior { public void fly(){ console。writeline('我会飞~!'。);}} class fly noway : fly行为{ public void fly(){//什么都不做,它就不会飞}}我把两个类放在一起,方便大家阅读,其实应该分开。看“夏夏”的行为:复制代码如下:类呱呱:呱呱行为{public void呱呱(){console。writeline('夏夏!'。);}} class squeak :呱呱行为{public void呱呱(){console.writeline ('squeak!'。);//橡皮鸭}} classmute呱呱:呱呱行为{public void呱呱(){console。writeline(' . ');//'诱饵鸭'不会叫}}行为做得好~复制鸭类的代码如下:公共抽象类鸭{公共飞行为飞行为;公共码头行为码头行为;public void perform quak(){ quack behavior . quak();} public void performFly(){ fly behavior。fly();} public virtual void swim(){ console。write line(' ~ ~ swim ~ ~ ');} public virtual void Display(){}}是一个简单的结构,不是吗?定义QuackBehavior和FlyBehavior,每个鸭子都会引用实现QuackBehavior接口的对象,这样就可以处理鸭子的行为。如果你想要啜饮的效果,你需要夸夸其谈对象来啜饮。现在,我们不需要关心什么是码头行为接口对象,只需要关心鸭子是如何被调用的。可以重用quackbehavior接口。你发现了吗?哪里可以重复使用?考虑一下,我以后再提出来。好了,现在我们来具体实现duck实体:复制代码如下:公共类mallard uck : duck { public mallard uck(){呱呱行为=new呱呱();fly behavior=new flywitwings();}公共覆盖无效显示(){控制台。writeline('我是一只美丽的绿头鸭!' );}} o(_)o的伟大工作将会完成。看程序:复制的代码如下:静态void main(string[]args){ Mallard UCK Mallard=new Mallard UCK();绿头鸭。显示();绿头鸭。swim();mallard . perform QuaK();mallard . performfly();}一目了然,这个程序做什么,怎么做,很简单吗?看运行结果:

代码已经贴好了,程序真的可以运行了。现在,让我们看看这个设计的最后一个概念:使用更多的组合,使用更少的继承。如您所见,使用组合构建系统具有很大的灵活性,不仅可以将算法族封装到类中,还可以在运行时动态改变行为。不知道什么是“运行时动态改变行为”?好了,我再演示一个,以美丽的绿头鸭为例:Duck类的最新修改:复制代码如下:公共抽象类duck { public fly behavior公共码头行为码头行为;public void perform quak(){ quack behavior . quak();} public void performFly(){ fly behavior。fly();} public virtual void swim(){ console。write line(' ~ ~ swim ~ ~ ');} public virtual void display(){ } public void setfly behavior(fly behavior flyb)//add { fly behavior=flyb;}}然后我会添加另一个火箭动力:复制代码如下:类fly rocket powered : fly behavior { public void fly(){ console。writeline('打鸡血!400米/秒,加速飞行!);}}看程序:复制代码如下:类程序{ static void main(string[]args){ mallard uck mallard=new mallard uck();绿头鸭。显示();绿头鸭。swim();mallard . perform QuaK();mallard . performfly();绿头鸭。setFlyBehavior(new FlyRockepowered());mallard . performfly();}}结果:

是动态添加的吗?修改容易吗?至于庸医行为界面的复用:你知道鸭角吗?猎人用这个东西模拟鸭子的叫声,引诱野鸭。这不是很好重用吗?O(_)o更多的重用仅限于你的想象~如果你仔细看了这个,那么下面的勋章就是给你的:你学会了军师设计模式

O(_)o你再也不用担心系统有什么变化了。策略制定者模式定义算法族,并分别对它们进行打包,以便它们可以相互替换。这种模式使得算法的改变独立于使用算法的用户。看完之后,如果觉得还不错,就点击推荐。O(_)o这是我的支持,谢谢。

版权声明:设计指南——一个由鸭子游戏触发的设计理念(多态、继承、抽象、界面、战略家模式)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。