3

たとえば、基本抽象クラスがあるとします

public abstract Foo
{
  IFlyable _fly;
  ISwimmable _swim;

  void performSwim()
  {
    _swim.swim();
  }

 void performFly()
 {
   _fly.fly();
 }
}

そして、システムに持つ動作/アルゴリズムを持っています

interface IFlyable { void fly(); }
interface ISwimmable { void swim(); }
interface IVoteable { void vote(); }

などなど

これで、IFlyable、ISwimmable などの具象を使用して、それを実装する複数のクラスができました。

class Bar: Foo { _swim = new ConcerteSwim(); }
class Baz: Foo { _fly = new ConcreteFly(); }

などなど

1 つは、Foo の基本クラスで戦略パターンを使用して動作を交換することです。

デコレーターパターンを使用して特定の動作でラップすることもできますが、デコレーターは基本クラスでラップするため、後でオブジェクトにさらに動作を追加する場合、基本クラスに触れずにオープンクローズ原則を実際に機能させるにはどうすればよいですか。これらの動作は、たとえばデコレータを呼び出すだけでなく、さらに追加すると異なるシグネチャを持つ可能性があるため

void performSwim()
{
     swimWithMoreSpeed() + foo.performSwim()
}

私の質問は、動作を追加する場合、どうすれば基本クラスを変更せずに IWeaponBehavior、ISomeBehaviour をクラスに追加できるかということだと思います。

たとえば、私はクラスを持ちたいです

public class XYF: Foo
{

}

しかし、私はそれにISomeBehaviourのいくつかの動作を与えたいのですが、これらの種類の動作でそれをラップすると言うことができる方法はありますか、またはここではConcreteFooがこれらの動作でラップし、具体的なxyzにインターフェースを実装するのではなく何かをしますこれにより、swimbehavior、nullbehaviour などの非常に多くの種類の具体的な動作クラスを実装することになりますが、そこから抜け出す方法はありません。

デザインパターンでこれを行う方法はありますか? それはほとんどパターンのハイブリッドのように見えます。

アヒルのように歩き、アヒルのように鳴くが、バッテリーが必要な場合は、抽象化に問題があるように思えます。

これが理にかなっていることを願っています。

4

3 に答える 3

0

来客パターンは?これにより、基本クラスの実装者は、新しい実装ごとに基本クラスを強制的に変更することなく、動作を変えることができます。

public interface IFlyable { void fly(); }
public interface ISwimmable { void swim(); }
public interface IVoteable { void vote(); }

public abstract class Animal
{
    public abstract void Accept(AnimalVisiter Visitor);
    //some common behaviour is here
    public bool LegsKicking { get; set; }
    public bool ArmsFlapping { get; set; }
}

//This class now absorbs new responisbilities, so base class doesn't have to
public class AnimalVisiter
{
    public void Visit(ISwimmable Subject)
    {
        Subject.swim();
    }

    public void Visit(IVoteable Subject)
    {
        Subject.vote();
    }

    public void Visit(IFlyable Subject)
    {
        Subject.fly();
    }
}

public class SwimmingHuman : Animal, ISwimmable
{
    public void swim()
    {
        LegsKicking = true;
    }

    public override void Accept(AnimalVisiter Visitor)
    {
        Visitor.Visit(this);
    }
}

public class VotingHuman : Animal, IVoteable
{

    public override void Accept(AnimalVisiter Visitor)
    {
        Visitor.Visit(this);
    }

    public void vote()
    {
        VoteCast = true;
    }
    //some specific behaviour goes here
    public bool VoteCast { get; set; }
}

public class SwimmingTiger : Animal, ISwimmable
{

    public void swim()
    {
        LegsKicking = true;
        //also wag tail, flap ears
    }

    public override void Accept(AnimalVisiter Visitor)
    {
        Visitor.Visit(this);
    }
}
于 2009-02-16T22:43:01.263 に答える
-2

だからここにこれに対する私の見解があります:

public enum ActionType
{
   Swim, Vote, Fly
};

public interface IBehavior
{
   public boolean ActionReady;
   public ActionType _type;

   public void performMyAction();
}

public abstract Foo
{
  IBevahior[] behaviors;

  // if you want to keep track of behavior states as on or off
  void perform()
  {
    for(int i = 0; i< behaviors.length; i++)
    {
       if(behaviors[i].ActionReady)
       {
          behaviors[i].performMyAction();
       }
    }
  }

  // if you want to call behaviors individually
  void performType(ActionType type)  // however you want to make the distinction
  {
     for(int i = 0; i < behaviors.length; i++)
     {
        if(behaviors[i].type = type)
        {
            behaviors[i].performMyAction();
        }
     }
  }
}

次に、ISwimmable などのインターフェイスを IBehavior から継承します。

于 2009-02-12T21:39:53.520 に答える