Değiştirilmiş Strateji Tasarım Modeli


11

Son zamanlarda Tasarım Desenlerine bakmaya başladım ve kodladığım bir şey, küçük bir fark dışında Strateji modeline mükemmel bir şekilde uyuyordu.

Temel olarak, algoritmaların bazıları (hepsi değil), ekstra bir parametreye veya iki tanesinin geçirilmesine ihtiyaç duyuyor.

Bu yüzden ikisine de ihtiyacım olacak

  • kendi hesaplama yöntemini çağırdığınızda onlara ekstra bir parametre iletmek

veya

  • bunları ConcreteAlgorithm sınıfında değişkenler olarak saklayabilir ve algoritmayı çağırmadan önce bunları güncelleyebilirim.

Bu ihtiyaç için bir tasarım modeli var mı / Strateji Modeline bağlı kalırken bunu nasıl uygulayabilirim?

İstemci nesnesini tüm algoritmalara geçirmeyi ve değişkenleri orada depolamayı, sonra yalnızca belirli bir algoritmaya ihtiyaç duyduğunda kullanmayı düşündüm. Ancak, bence bu hem hantal, hem de strateji modelinin noktasını alt ediyor.

Sadece açık bir şekilde Java'da uyguluyorum ve bu yüzden isteğe bağlı parametrelerin lüksüne sahip değilim (bunu güzelce çözer).


C ++ gibi isteğe bağlı parametreler hiçbir şeyi çözmez, çünkü bunlar birden fazla aşırı yüklenmiş yöntemi tanımlamak için bir kısayoldur.
maaartinus

Ek parametreleri kullanmadan önce değiştirmek zorunda olduğum bir yerde saklamaktan kaçınmaya çalıştım. Bu şekilde ConcreteAlgorithm'i durumsal hale getirirsiniz, böylece diğer yöntemlere veya iş parçacıklarına kolayca geçirilemez. Dahası, parametreleri ayarlamayı unutmak çok kolaydır.
maaartinus

Yanıtlar:


5

Samuel, stratejilerin her birinin ortak bir sınıfa aldığı parametreyi kapsüllemek ve daha sonra bazı stratejilerinizin özellikle ihtiyaç duyduğu daha fazla davranış eklemek için bu ortak Parametre sınıfını genişletmek mümkün mü?

Örneğin

StrategyParameter //Base strategy parameter that most of the strategies need
        ^
        |
        |
SpecialStrategyParameter // will be used for strategies that need more parameter

Ardından, strateji hiyerarşisini şöyle tanımlayın:

Interface MyStrategy {
   void myStrategyMethod(StrategyParameter parameter);
}

class MyNormalStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

yukarıdaki stratejiyi şu şekilde adlandırın: myNormalStrategyInstance.myStrategyMethod(strategyParameter);

class MySpecializedStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}

yukarıdaki stratejiyi aşağıdaki SpecialStrategyParametergibi örnek geçerek arayın :mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);

Bir şey net değilse lütfen güncelleyin. Açıklamak / açıklamaktan mutluluk duyacağız.


2
-1 downcast gerektirir, tasarım kapsülleme tatili. Söz konusu tasarımda bir gelişme olmasına rağmen, bu kediyi cildin daha iyi yolları var.
tallseth

@tallseth Ben de mahzun görüyorum. Ama daha iyi yollar görmüyorum. Lütfen daha iyi bir çözüme dikkat çeker misiniz? Bir makale falan?
Narek

Aslında evet. @ Jordão, sorudaki detaylara dayanarak, tercih edeceğim cevaba sahiptir. Bu cevap strateji modelinin güçlü yönlerini oynuyor. Bu cevaptaki yaklaşımla devam StrategyParameteretseydik, tıpkı bir DTO gibi tüm olası parametreleri içermesini isterdim . Stratejinin bazı uygulamaları onları görmezden gelebilir. Bazı durumlarda, bu en iyi yaklaşımdır. Bu tür sorunlar için bağlam kraldır.
tallseth

4

Stratejinizi netleştirmeniz gerekiyor .

Her şey algoritmalarınızı nasıl kullandığınıza bağlıdır . Müşteri sınıfınızın farklı strateji uygulamalarını dönüşümlü olarak kullanması için hepsinin ortak bir soyutlamaya sahip olması gerekir . Eğer aynı arayüzü takip etmezlerse, belki de ihtiyacınız olan şey farklı soyutlamalar .

İnşaatta somut sınıfları parametreleştirdiğiniz daha önce yapılandırılabilir stratejiler kullandım :

interface Strategy {
  int calculate();
}

class ConcreteStrategyThatNeedsAParameter implements Strategy {
  private final int param;
  public ConcreteStrategyThatNeedsAParameter(int param) {
    this.param = param;
  }
  public int calculate() { 
    // uses param...
  }
}

Şimdi, birisinin hala bu sınıfın bir örneğini oluşturması ve istemcinize iletmesi gerekiyor. Ancak müşterinizin hala yalnızca Strategyarayüz hakkında bilgi sahibi olması gerekir .

Strateji yönteminiz parametreleri alıyorsa da çalışır , ancak müşteriniz bu parametreleri bilir ve birlikte çalıştığı tüm uygulamalara iletir.


İstemci, parametreyi sağlayan içeriğe sahip istemcidir.
andyczerwonka

1

İmza arayüzde açıkça tanımlandığı sürece, yine de Strateji modeline uygundur.

Yazılan desenler, beklenen davranışı hala gösteren mutlak en basit formdur, böylece orijinal amacı koruduğunuz sürece bunları süsleyebilirsiniz. Tabii ki bu kalıbı takip etmek istediğinizi varsayar. Bir desen uymuyorsa veya sadece orada olduğu için kullanmanın bir anlamı yoktur, ancak sizin durumunuzda iyi olduğunu düşünüyorum.


0

peakit tarafından sağlanan yukarıdaki cevabı genişleterek - soyutlama kullanabilirsiniz. Burada peakit'in kodunu kullanıyorum -

Arayüz MyStrategy { abstract void myStrategyMethod (StrategyParameter parametresi); }

MyNormalStrategy sınıfı MyStrategy'yi genişletir {public override void myStrategyMethod (StrategyParameter parametresi) {// mantığı buraya uygulayın}}

sınıf MySpecializedStrategy, MyStrategy'yi genişletiyor {public override void myStrategyMethod (StrategyParameter parametresi, ExtraStrategyParameter extraParameter) {// mantığı buraya uygulayın} }

Sorunuzu doğru anlarsam, belirli algoritmalara ekstra bir parametre aktarmak istediniz mi? Lütfen aradığınız şeyin bu olup olmadığını bize bildirin.


0

Tasarım modelleri kitabına bakarsanız, geçirilen parametrelerin daha azını kullanan veya hiç kullanmayan bazı SimpleStrategy'lerin var olması veya parametrelerin tek boyutlu bir herkese / en az ortak çarpan olması yanlış değildir. Buradaki tasarım seçimi, bunun kullanılmayan ekstra işleme açısından sizi incitip incitmediğidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.