Подтвердить что ты не робот

Изменение порядка метода, вызывающего разные экземпляры класса

Каков наилучший способ манипулирования заказами, делаются на основе некоторых условий (кроме написания их снова с другим порядком)?

Скажем, есть класс Person, и каждый объект Person представляет другого человека.

class Person{
    int eatingPriority = 3;
    int sleepingPriority = 2;
    int recreationPriority = 1;

    void eat() {/*eats*/}
    void sleep() {/*sleeps*/}
    void watchTv() {/*watches tv*/}

    void satisfyNeeds() {
        //HOW TO DO THIS
    }
}

Как я могу заставить методы satisfyNeeds() вызывать другие три метода на основе их приоритета?

Примечание. Я хочу дать понять, что приоритеты могут меняться от Person to Person.

4b9b3361

Ответ 1

Вы можете использовать этот код

import java.util.Arrays;  // must be imported
int[] priorities = {sleepPriority, eatPriority, recreationPriority};
Arrays.sort(priorities);
for (int i=priorities.length-1; 0<=i; i--) {
    int priority = priorities[i];
    if (priority == sleepingPriority) { sleep(); }
    if (priority == eatingPriority) { eat(); }
    if (priority == recreationPriority) { watchTv(); }
}

В основном, он ставит приоритеты в массиве, сортирует массив и запускает цикл for для запуска этих функций.

Ответ 2

Вы можете сделать это с помощью 1 класса и 1 интерфейса.

public class Person {
    int eatingPriority = 3;
    int sleepingPriority = 2;
    int recreationPriority = 1;

    PriorityQueue<Action> actions;

    void eat() { }

    void sleep() { }

    void watchTv() { }

    public Person() {
        actions = new PriorityQueue<Action>(new Comparator<Action>() {
            @Override
            public int compare(Action o1, Action o2) {
                return o2.getPriority() - o1.getPriority();
            }
        });

        actions.add(new Action() {
            @Override
            public int getPriority() {
                return eatingPriority;
            }
            @Override
            public void execute() {
                eat();
            }
        });

        actions.add(new Action() {
            @Override
            public int getPriority() {
                return sleepingPriority;
            }
            @Override
            public void execute() {
                sleep();
            }
        });

        actions.add(new Action() {
            @Override
            public int getPriority() {
                return recreationPriority;
            }
            @Override
            public void execute() {
                watchTv();
            }
        });
    }

    public void satisfyNeeds() {
        for (Action action : actions) {
            action.execute();
        }
    }

    interface Action {
        public int getPriority();
        public void execute();
    }
}

Ответ 3

Вот еще одна возможная реализация:

abstract class Need {
  abstract void satisfy();
}

class Eat extends Need {
  @Override
  public void satisfy() { /* eat ...*/}
}

class Sleep extends Need {
  @Override
  public void satisfy() { /* sleep ...*/}
}

class DrinkBeer extends Need {
  @Override
  public void satisfy() { /* drink beer ...*/}
}

class Person{
  // TreeMap will sort the map in the key natural order (a int here)
  private Map<Integer, Need> needs = new TreeMap<>();    

 Person() {
   add(new Eat(), 3);
   add(new Sleep(), 2);
   add(new DrinkBeer(), 1);
 }

 void add(Need need, int priority) {
   needs.put(Integer.valueOf(priority), need);
 }

 void satisfyNeeds() {
    for(Need need : needs.values())
      need.satisfy();
  }
} 

Ответ 4

Для этого решения потребуется Java 8:

class Person {

    void eat() {};
    void sleep() {};
    void watchTv() {};

    // Being in a List you can easily reorder the needs when you want to
    List<Runnable> needs = Arrays.asList(this::eat, this::sleep);

    // Alternatively, you can use a Map<Runnable, Integer> where the value is your
    // priority and sort it (see http://stackoverflow.com/q/109383/1296402)

    void satisfyNeeds() {
        needs.forEach(r -> r.run());
    }
}

Ответ 5

Поиск правильного порядка трех элементов можно сделать так:

 void satisfyNeeds() {
     boolean eatFirst = eatingPriority>Math.max(sleepingPriority,recreationPriority);
     if(eatFirst) eat();
     if(sleepingPriority>recreationPriority) {
         sleep();
         watchTv();
     }
     else {
         watchTv();
         sleep();
     }
     if(!eatFirst) eat();
  }

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

Ответ 6

Вы должны ввести свойство map в класс Person, где приоритеты методов, например:

class Person {

...
private Map<Integer, Method> methodsPriority = new HashMap<>();
...
 public Person setEatingPriority(int priority) {

  methodsPriority.put(priority, /* put 'eat' method reference here*/);
  return this;
 }

 public Person setSleepingPriority(int priority) {

  methodsPriority.put(priority, /* put 'sleep' method reference here*/);
  return this;
 }

 public Person setWatchingTVPriority(int priority) {

  methodsPriority.put(priority, /* put 'watch TV' method reference here*/);
  return this;
 }

 public void satisfyNeeds() {

  Collection<Integer> keys = methodsPriority.keySet();
  Collections.sort(keys);
  for(Integer key: keys)
   methodsPriority.get(key).invoke(this);
 }



...
}

И его можно использовать следующим образом:

Person Anna = new Person()
.setEatingPriority(1)
.setSleepingPriority(2)
.setWatchingTVPriority(3);

Person Bob = new Person()
.setEatingPriority(3)
.setSleepingPriority(2)
.setWatchingTVPriority(1);

Anna.satisfyNeeds();
Bob.satisfyNeeds();