Oop 重构包含半相关和半不相关函数的两个类时使用哪种设计模式?
我有两个物体,鸟和狗Bird和Dog对大约50%的方法/属性有相同的实现,但对其他50%的方法/属性有不同的不相关的方法和属性 我正在重构,我不知道什么是最好的策略 我尝试定义一个超类Animal来实现超类中的常用方法,并让子类定义自己的方法/属性 我写了一个工厂,返回一个或另一个-这一切似乎都是正确的。。。但是我在编写调用代码时感到困惑。。e、 gOop 重构包含半相关和半不相关函数的两个类时使用哪种设计模式?,oop,design-patterns,Oop,Design Patterns,我有两个物体,鸟和狗Bird和Dog对大约50%的方法/属性有相同的实现,但对其他50%的方法/属性有不同的不相关的方法和属性 我正在重构,我不知道什么是最好的策略 我尝试定义一个超类Animal来实现超类中的常用方法,并让子类定义自己的方法/属性 我写了一个工厂,返回一个或另一个-这一切似乎都是正确的。。。但是我在编写调用代码时感到困惑。。e、 g public class Animal{ public string Talk(){ return "yak yak yak"; } pub
public class Animal{
public string Talk(){ return "yak yak yak";
}
public class Dog:Animal{
public string Walk(){ return "walk walk walk"; }
}
public class Bird:Animal{
public string Fly(){ return "flap flap flap"; }
}
...
Animal thing = CreatureFactory.GetCreature(modifier);
当我想用东西说话没有问题
Debug.Print(thing.Talk());
但是,作为程序员,当我知道我想要它飞行时,我会把它投给鸟吗?这似乎是错误的。。。但是在狗上定义飞的方法也似乎是错误的。你要么把它扔给鸟:
Debug.Print(((Bird)thing).Fly());
或者你一直把它当作一只鸟:
// depending on how the factory works, might not need the cast
Bird thing = (Bird) CreatureFactory.GetCreature(modifier);
Debug.Print(bird.Fly());
我想说:
如果你的狗也有一个方法,使“运动”的想法,我会改变名称的飞行和步行“移动”,然后叫它。
如果你的狗没有类似的东西,开发人员就不能在任何对象上调用它,因为不是所有动物都能飞:)首先,我会在名为
Move()
的基类上放置一个虚拟方法,并在派生类中重写它
(以下是C#)
但要回答您的问题,如果您希望动物在(且仅在)它能飞的情况下移动,您可以定义一个IFlyingAnimal
接口,并使用Bird
实现它。然后,您可以测试动物是否实现了该接口。如果是,则将其强制转换为iflynganimal
,并调用其Fly()
方法
public interface IFlyingAnimal {
string Fly();
}
public class Bird : Animal, IFlyingAnimal {
public string Fly(){ return "flap flap flap"; }
}
//later, in your main program
public string FlyIfYouCan(Animal animal) {
if (animal is IFlyingAnimal)
return ((IFlyingAnimal)animal).Fly();
return "I can't fly!";
}
您不必使用接口;如果(动物是鸟),您可以使用
。但这样做是更好的练习;鸟类不是唯一会飞的动物,所以你的决定是基于你的物品的功能,而不是它是什么。这就是接口的用途。我的方法是让工厂方法返回具体类型,而不是超类。您仍然可以将它传递给可以在超类上操作的方法,但是您在需要时可以使用具体类的一项,而不需要强制转换它
Bird bird = CreatureFactory.GetBird();
或
现在,您仍然可以将它们用作动物
public class Trainer
{
public void TeachToSpeak( Animal animal )
{
...
animal.Talk();
}
}
但是,由于它们被输入到具体的类中,您可以适当地使用它们不共享的方法。举个例子,当您希望您的动物
飞行时,执行飞行的类与错误的类一起工作——它应该使用鸟
本身或一些ICanFly
接口
虽然其他答案说您可以通过强制转换来实现,但代码的可读性将因此受到影响。当工厂创建对象时,绝对没有理由将这些对象强制转换为其他类型。还有一个确凿的证据表明,当您开始强制转换到其他类型时,您的类违反了单一责任原则 这个想法不错,只是很多鸟也会走路。@MattBall:所以提供一个三维矢量和一个三维网格。现在你可以检查它是否在飞。如果你想让它飞,为什么不把它声明为鸟呢?想想这个:你怎么知道你有一只鸟?为什么要让它飞行()。可能是因为某些输入满足了某些条件,对吗?您的动物需要DoSomethingWith(输入)
。鸟和狗应该按他们认为合适的方式执行。谢谢所有回答的人。
Dog dog = CreatureFactory.GetDog();
public class Trainer
{
public void TeachToSpeak( Animal animal )
{
...
animal.Talk();
}
}