Определение всей функциональности абстрактного класса с интерфейсом - PullRequest
0 голосов
/ 17 марта 2019

Я пишу симулятор о облачных вычислениях в Java.Мой код выполняет следующие действия:

  1. Создание развертывания
  2. Передача его в симуляцию
  3. ???
  4. Прибыль.

В настоящее время существуют различные типы развертываний (они имеют атрибуты, которые соответствуют различным статистическим распределениям), но все они имеют общие атрибуты и методы (методы start, end, size и update).Естественно, я смоделировал развертывание как абстрактное.

Но тогда я не могу сослаться на это в части симуляции (что хорошо, так как я хочу, чтобы симуляция не знала, какой тип развертывания он обрабатывает (хотя есть один модуль, который должен выполнить проверку типа))).Тем не менее, я должен вызывать методы развертывания, поэтому мой абстрактный класс теперь реализует интерфейс с именем deployable.С этой моделью я могу делать такие вещи, как:

// In a cluster class of the simulation
for(deployable d : deployments){
    d.updateOnTimestep();
}

Через некоторое время я пришел к тому, что мой интерфейс становится все больше и больше.Кроме того, мне пришлось реализовать информационный объект, чтобы получить доступ к атрибутам развертывания (опять же, каждое развертывание имеет и другие атрибуты).Пример:

// In a class that calculates some probabilties
public void evaluate(deployable d){
    // retrieve deployment information
    d.getInfo().getSpecificParam();
}

И теперь я думаю, что если бы я не смоделировал развертывание как абстрактное, мне не понадобился бы интерфейс, и мой код выглядел бы более симпатично.Но опять же, я действительно считаю, что развертывание должно быть абстрактным (например, я не хочу, чтобы какой-то другой программист инициализировал развертывание без запуска).

Каково ваше мнение по этому поводу?- Я пытался найти некоторые шаблоны проектирования, но я не опытный программист и немного растерялся.Любая помощь приветствуется.

Редактировать: Как и предлагалось, я хотел бы дать больше фрагментов кода

public abstract class Deployment implements deployable{
    // Attributes
    int size;
    int start;
    //...
    // Interface methods, that all deployments use (only a snippet)
    public void removeScaleOut(ScaleOut sc){
        // ...
    }
    public void decreaseSize(int decreasement){
        this.size -= decreasement;
    }
    public void reassignID(String id){
        this.id = id;
    }
}

Теперь интерфейс развертываемый:

public interface deployable {

public void updateOnTimeStep();
public void updateOnAccept();
public void updateOnSpawn(ScaleOut sc);
public void updateOnDeath();
public DeploymentInformation getInformation();
public void spawnScaleOut();
public void reassignID(String id);
public void increaseSize(int increasement);
public void decreaseSize(int decreasement);
public void addActiveScaleOut(ScaleOut scaleOut);
public void removeActiveScaleOut(ScaleOut scaleOut);
public void removeScaleOut(ScaleOut scaleOut);

}

Наконец, класс, расширяющий абстрактный класс:

public class GammaDeployment extends Deployment {

// Gamma Prior variables
private double spawnShape = 0; 
// many more...

// Variables associated with the computation of the conjugate priors.
private int pastRequests;
private int pastSpawnSizeSum;
private int overallDeadJobs = 0;
private int sumRealizedJobLifeTime =0;

// Update methods from the interface deployable.
@Override
public void updateOnTimeStep() {
    for(ScaleOut sc : activeScaleOuts) {
        sumRealizedJobLifeTime += sc.getVms().size();
    }
    age++;
}

@Override
public void updateOnSpawn(ScaleOut sc) {
    pastRequests += sc.getVms().size();
    pastSpawnSizeSum =+ sc.getSize();
}

@Override
public void updateOnDeath() {
    overallDeadJobs++; // virtual machines death.
}

//  The info object only holds attributes
@Override
public DeploymentInformation getInformation() {
    GammaDeploymentInformation gdi = new GammaDeploymentInformation(start,age,id,size,scaleOuts,this);
    gdi.setAge(age);
    gdi.setSize(size);
    gdi.setScaleOuts(scaleOuts);
    gdi.setActiveScaleOuts(activeScaleOuts);
    gdi.setSizeScale(getSizeScale());
    gdi.setSizeShape(getSizeShape());
    gdi.setSpawnScale(getSpawnScale());
    gdi.setSpawnShape(getSpawnShape());
    gdi.setDeathScale(getDeathScale());
    gdi.setDeatRate(getDeatRate());
    // Id has also to be set, since it may change over the course of the simulation.
    gdi.setId(id);
    return gdi;
}

}

А теперь пример использования в части симуляции, здесь меня беспокоит, что мне нужноцепочка многих функций вместе, чтобы получить атрибут размера.

public void assign(deployable deployment, Cluster cluster) {
    int deploymentSize = deployment.getInformation().getScaleOuts().get(0).getSize();
    // Update sizes...

    // Add scale out to active scale outs. 
    deployment.addActiveScaleOut(deployment.getInformation().getScaleOuts().get(0));
    // Remove initial request.
    deployment.removeScaleOut(deployment.getInformation().getScaleOuts().get(0));
}

Это приводит к очень длинным операторам if в некоторых классах:

// Check if deployment is dead
if(currentDeployment.getInformation().getActiveScaleOuts().isEmpty()
                && currentDeployment.getInformation().getScaleOuts().isEmpty()) {
...