Bazı kodları yeniden düzenleme üzerinde çalışıyorum ve sanırım tavşan deliğinden aşağı ilk adımı atmış olabilirim. Örneği Java ile yazıyorum, ancak sanırım agnostik olabilir.
Foo
Olarak tanımlanan bir arayüzüm var
public interface Foo {
int getX();
int getY();
int getZ();
}
Ve bir uygulama olarak
public final class DefaultFoo implements Foo {
public DefaultFoo(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
private final int x;
private final int y;
private final int z;
}
Ben de MutableFoo
eşleşen mutasyonlar sağlayan bir arayüz var
/**
* This class extends Foo, because a 'write-only' instance should not
* be possible and a bit counter-intuitive.
*/
public interface MutableFoo extends Foo {
void setX(int newX);
void setY(int newY);
void setZ(int newZ);
}
MutableFoo
Bunun olabileceği birkaç uygulama var (henüz uygulamadım). Onlardan biri
public final class DefaultMutableFoo implements MutableFoo {
/**
* A DefaultMutableFoo is not conceptually constructed
* without all values being set.
*/
public DefaultMutableFoo(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public void setX(int newX) {
this.x = newX;
}
public int getY() {
return y;
}
public void setY(int newY) {
this.y = newY;
}
public int getZ() {
return z;
}
public void setZ(int newZ) {
this.z = newZ;
}
private int x;
private int y;
private int z;
}
Bunları ayırmamın nedeni, her birinin kullanılmasının eşit derecede olası olmasıdır. Yani, bu sınıfları kullanan birisinin değişmez bir örnek isteyeceği gibi, muhtemelen değişebilir bir örnek isteyeceklerdir.
Sahip olduğum birincil kullanım durumu, StatSet
bir oyun için belirli savaş detaylarını (isabet noktaları, saldırı, savunma) temsil eden bir arayüz . Bununla birlikte, "etkili" istatistikler veya gerçek istatistikler, asla değiştirilemeyen temel istatistiklerin ve artırılabilecek eğitimli istatistiklerin bir sonucudur. Bu ikisi
/**
* The EffectiveStats can never be modified independently of either the baseStats
* or trained stats. As such, this StatSet must never provide mutators.
*/
public StatSet calculateEffectiveStats() {
int effectiveHitpoints =
baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
int effectiveAttack =
baseStats.getAttack() + (trainedStats.getAttack() / 4);
int effectiveDefense =
baseStats.getDefense() + (trainedStats.getDefense() / 4);
return StatSetFactory.createImmutableStatSet(effectiveHitpoints, effectiveAttack, effectiveDefense);
}
eğitimli Stajyerler, her savaştan sonra
public void grantExperience() {
int hitpointsReward = 0;
int attackReward = 0;
int defenseReward = 0;
final StatSet enemyStats = enemy.getEffectiveStats();
final StatSet currentStats = player.getEffectiveStats();
if (enemyStats.getHitpoints() >= currentStats.getHitpoints()) {
hitpointsReward++;
}
if (enemyStats.getAttack() >= currentStats.getAttack()) {
attackReward++;
}
if (enemyStats.getDefense() >= currentStats.getDefense()) {
defenseReward++;
}
final MutableStatSet trainedStats = player.getTrainedStats();
trainedStats.increaseHitpoints(hitpointsReward);
trainedStats.increaseAttack(attackReward);
trainedStats.increaseDefense(defenseReward);
}
ama savaştan hemen sonra artmıyorlar. Belirli eşyaları kullanmak, belirli taktikleri kullanmak, savaş alanının akıllıca kullanılması farklı deneyim kazandırabilir.
Şimdi sorularım için:
- Arabirimleri erişimciler ve mutasyoncular tarafından ayrı arabirimlere bölmek için bir ad var mı?
- Onları eşit şekilde kullanılmaları muhtemelse bu şekilde 'doğru' yaklaşım mı bölmek, yoksa bunun yerine kullanmam gereken daha farklı, daha kabul edilmiş bir kalıp var mıdır (örneğin
Foo foo = FooFactory.createImmutableFoo();
, geri dönebilirDefaultFoo
veya geri döndüğüDefaultMutableFoo
için gizlidir )?createImmutableFoo
Foo
- Arayüz hiyerarşisini karmaşıklaştırmak için bu kalıbı kullanmanın hemen öngörülebilir dezavantajları var mı?
Bu şekilde tasarlamaya başlamamın nedeni, bir arabirimin tüm uygulayıcılarının mümkün olan en basit arabirime uyması ve başka bir şey sağlamaması gerektiği fikrindeyim. Arayüze ayarlayıcılar ekleyerek, etkili istatistikler artık bölümlerinden bağımsız olarak değiştirilebilir.
Bunun için yeni bir sınıf oluşturmak EffectiveStatSet
, işlevselliği hiçbir şekilde genişletmediğimiz için pek mantıklı değil. Uygulamayı değiştirebilir ve EffectiveStatSet
iki farklı bileşimi oluşturabiliriz StatSets
, ancak bunun doğru çözüm olmadığını hissediyorum;
public class EffectiveStatSet implements StatSet {
public EffectiveStatSet(StatSet baseStats, StatSet trainedStats) {
// ...
}
public int getHitpoints() {
return baseStats.getHitpoints() + (trainedStats.getHitpoints() / 4);
}
}