假设我有一个对象,Car,它有各种方法......不同?也许像Blob一样? (如在反模式中,“blob”)这些方法在不同的集合中运行,并且在功能上并不真正十字交叉。
Car
# methods related to suburban driving
->foo1
->foo2
# methods related city driving
->bar3
->bar4
现在让我们说我想添加“越野驾驶”作为我的汽车对象可以支持的案例之一。如果我向Car对象添加方法,是不是让它更像blob?
Car (augmented)
# methods related to suburban driving
->foo1
->foo2
# methods related city driving
->bar3
->bar4
# methods related off road driving
->blah5
->blah6
我应该:
答: Subclass Car 。我可以制作一个OffRoadCar扩展Car对象。但是如果Car和OffRoadCar共享相同的数据/状态,并且只是方法不同呢? OffRoadCar只比汽车更具体“行动”,但没有更具体的描述,也没有独特的领域。因此实例化OffRoadCar毫无意义。
OffRoadCar extends Car
# methods related off road driving
->blah5
->blah6
B:使用静态方法消耗汽车。喜欢OffRoadAdventure-> Embark(Car)。因此,OffRoadAdventure类接受一个Car对象并使用它。
在C#中,这将被称为扩展方法。
我想另一种方法是 Blob反模式的解决方案是什么?是子类吗?是扩展方法吗?
另外,我想要解决这些方法的另一个原因是,如果它们的实现会产生一些成本,比如包含其他类/包?我不希望核心类的用户经常为他们永远不会使用的东西买单。我认为让少数人明白成本对大多数人来说是值得的。它使依赖图更精确(而不是像blob一样)。
PS - 实现语言是Perl。
答案 0 :(得分:2)
使用Perl,你应该好好看看Moose和角色。
package Suburban;
use Moose::Role;
requires 'wheels';
sub 'foo1' {
...
}
sub 'foo2' {
...
}
package City;
use Moose::Role;
requires 'wheels';
sub 'bar3' {
...
}
sub 'bar4' {
...
}
package Offroad;
use Moose::Role;
requires 'wheels';
sub 'blah5' {
...
}
sub 'blah6' {
...
}
package UltraCar;
use Moose;
with qw/ Offroad City Suburban /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );
package RentalCar;
use Moose;
with qw/ City Suburban /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 4 );
package Tricycle;
use Moose;
with qw/ Offroad /;
has 'wheels' => ( is => 'rw', isa => 'Int', default => 3 );
您甚至可以在运行时添加和删除角色。
答案 1 :(得分:0)
我认为你走在正确的轨道上。一个优雅的解决方案是让OffRoadCar
从Car继承并覆盖其Drive()
方法。这样,你可以说:
Car myCar = new OffRoadCar();
myCar.Drive();
这将在子类中调用重写的Drive()
方法,并且您不会在单个“blob”中使用大量方法。以下是Drive()
中OffRoadCar
方法的显示方式:
@Override
public void Drive()
{
/* code */
}
答案 2 :(得分:0)
您可以使用某种形式的Decorator pattern,而不是对Car
类进行子类化。
这里,基础ORM类和装饰器(比如OffRoadDecorator
)实现了一些通用接口,每个装饰器的行为可以动态地添加到原始类中。
这里的关键区别在于,可以在同一个Car
类上使用多个装饰器,并且由您的实现来说明它们应该如何交互。没有什么可以阻止你使用OffRoadDecorator
和SuburbanDecorator
装饰你的课程,你可以确定装饰师对汽车的确切含义。
(P.S。抱歉,我没有提供任何代码示例;我的Perl非常糟糕。请查看this page以获取其他一些示例。)
答案 3 :(得分:0)
不是真的答案马克,我不确定你想深入研究这个问题,但你可以研究一下方法解决方案的概念。使用mro允许您执行广度优先搜索,而不是标准深度优先搜索方法。有关详情,请参阅有关CPAN的this page和brian d foy的文章Use the C3 method resolution order in multiple inheritance。
答案 4 :(得分:0)
郊区,城市和越野驾驶听起来像算法。策略模式可能有助于将Context作为Car。