好吧,假设我有一个类,X和X是与其他对象有聚合关系的东西。假装X是一个足球场。
X满是观众。然而,每个观众对特定活动的行为不同。而不是IF语句,我希望不同的行为在观众类中,以便我可以使用动态绑定。
然而,问题在于观众所进行的行为会影响“足球场”课程。所以我想把“这个”从足球场的课程,通过一种方法传递给观察者课程,以便观众课能够为足球场的课程做些什么?
public class SoccerStadium{
SpecatorInterface s = new Spectator();
public void SpectatorBehaviour(){
s.doSomething(this);
}
public void doSomethingthingBySpecator(){
}
}
public class Spectator implements SpecatorInterface{
public void doSomething(SoccerStadium s){
s.doSomethingthingBySpecator();
}
}
我只想这样做,以便我可以使用动态绑定并改变Specator.doSomething()
中的行为,这样我可以将许多不同类型的SpectatorSuperClass作为传递给SoccerStadium的属性,然后具有不同的行为。
编辑:如果我通过Spectator构造函数将Stadium的引用传递给Specator,而不是传递this
,该怎么办?
答案 0 :(得分:3)
这不是“糟糕的编程”,因为它紧密coupled。传递this
指针并没有什么本质上的错误,但它很快就会变得混乱。如果没有更多的信息,我们真的不能说更多。
答案 1 :(得分:2)
我认为使用它作为参数没有问题。不过,我不喜欢new Spectator()
课程中硬编码的SoccerStadium
来电。我相信你应该有一个createSpectator
方法的工厂,它可以接收一个参数,表明你打算创建哪种类型的观众。
答案 2 :(得分:2)
我通过让体育场成为Spectator派遣事件的订户来解除关系。
public class SoccerStadium
{
ISpectator s = new Spectator();
public SoccerStadium()
{
s.DidSomething+=DoSomethingthingBySpecator;
}
public void SpectatorBehaviour()
{
s.DoSomething();
}
public void DoSomethingthingBySpecator(object sender,EventArgs e)
{
Console.WriteLine("spectator did something");
}
}
public interface ISpectator
{
event EventHandler DidSomething;
void DoSomething();
}
public class Spectator:ISpectator
{
public event EventHandler DidSomething;
public void DoSomething()
{
var ev=DidSomething;
if(ev!=null)
{
ev(this,EventArgs.Empty);
}
}
}
......所以Spectator现在有办法与任何有兴趣的人沟通,但不需要了解它。
答案 3 :(得分:2)
正如人们所说,紧密耦合和你正在做的事情绝对没有错。但是,如果您想要进行一些解耦,请使用经典的访问者模式。
public interface SpectatorVisitor {
...
void visit(Spectator spectator);
}
public class Spectator {
...
public void accept(SpectatorVisitor visitor) {
visitor.visit(this);
}
}
public class Stadium {
...
spectator.accept(new StadiumSpectatorVisitor());
}
如果需要,可以更改访问方法签名以接受某种状态对象。否则你可以简单地在Spectator类上定义相关方法,并让访问者收集改变体育场所需的信息。
例如:
public class Spectator {
private Team supports;
public Team getSupports() {
return supports;
}
public void accept(SpectatorVisitor visitor) {
visitor.visit(this);
}
}
public class SupportedTeamVisitor {
private Map<Team, AtomicLong> supportCount = new HashMap<Team, AtomicLong>();
public void visit(Spectator spectator) {
Team supports = spectator.getSupports();
if (! supportCount.contains(supports)) {
supportCount.put(team, new AtomicLong(0));
}
supports.get(team).incrementAndGet();
}
public Map<Team, AtomicLong> getSupportCount() {
return supportCount;
}
}
public class Stadium {
public long getSupportCount(Team team) {
SupportTeamVisitor visitor = new SupportedTeamVisitor();
for (Spectator spectator : spectators) {
spectator.accept(visitor);
}
AtomicLong count = visitor.getSupportCount().get(team);
return (count == null) ? 0 : count.get();
}
}
有意义吗?
答案 4 :(得分:1)
你的实施绝对没问题,我以前见过这种事。是的,您可以通过Spectator构造函数来保持体育场参考,这可能比每次需要时通过参考发送更清晰。
但是,我不太喜欢它;我更喜欢内部课程。目前还不完全清楚你要做什么,但这样的事情是可能的:
public class Outer {
private int someVariable=0;
public void someMethod(){
ExtendsInner ei = new ExtendsInner();
ei.innerMethod();
System.out.println(someVariable);
}
private void anotherMethod(){
someVariable++;
}
public abstract class Inner {
public abstract void innerMethod();
}
public class ExtendsInner extends Inner{
public void innerMethod(){
anotherMethod();
someVariable++;
}
}
public static void main(String[] args){
Outer o = new Outer();
o.someMethod();
}
}
不幸的是,你必须将你所有的“旁观者”类放在你的另一个类中,这可能会导致一个非常长的文件,因而是丑陋的代码。
但是,我认为你绝对应该避免做这两件事,因为这肯定会使你的代码过于复杂。
答案 5 :(得分:1)