программа банковского счета с использованием aspectj - PullRequest
0 голосов
/ 24 апреля 2020

Я хочу написать java программу, которая будет отслеживать банковский счет

, сейчас у меня есть следующая простая программа:

public class account
{
    private double balance;
    private String owner;
    public account(double x, String s) { balance=x; owner=s; }
    public String owner() { return owner; }
    public void withdraw(double a) { balance -= a; }
    public void deposit(double a) { balance += a; }
    public void printbalance() { System.out.println(balance); }

    // main for testing:
public static void main(String[] argv)
{
      account a1 = new account(2000,"you boss");
      account a2 = new account(1000,"me nerd");
      a1.deposit(400);
      a2.withdraw(300000);   // not enough money!
      a2.withdraw(-500000); // trying to cheat!
      a1.printbalance();
      a2.printbalance();
}//main
} // account

И я хочу добавить в эта программа использует аспектj следующее:

1 - я хочу, чтобы аккаунт не выводил большую сумму текущего баланса и снимал отрицательные числа.

2 - также я хочу, чтобы это предотвратить введите отрицательные числа.

3 - Мне нужно добавить графический интерфейс, (кнопки)

4 - добавить секретный пин-код или пароль, которые необходимо ввести, прежде чем клиент сможет совершить транзакцию.

5 - отслеживать все транзакции (с учетом aws и депозиты), сделанные на счете, и распечатывать отчет по запросу.

Буду признателен за вашу помощь. Спасибо.

privileged aspect newAccount
{
  //withdraw (prevent withdraw negative numbers and number greater than the   //current balance) 
    void around(account a, double x) : execution(void account.withdraw(double)) && target(a) && args(x){
        if(x > a.balance){
            System.out.println("not enough money!");
            return;
        }else if(x < 0){
            System.out.println("trying to cheat!");
            return;
        }
        proceed(a, x);
    }

//Deposit: prevent deposit negative number
    void around(double x) : execution(void account.deposit(double)) && args(x){
        if(x < 0){
            System.out.println("trying to  deposit negtive money!");
            return;
        }
        proceed(x);
    } 

    after() : execution(public static void *.main(String[])){
        account.a3 = new account(3000,"he nerd");
        a3.deposit(-100);
        a3.printbalance();

    }

//To Do: pin secret password 
//To Do: Transaction Record
}

1 Ответ

1 голос
/ 27 апреля 2020

Я вижу, что вы все еще изучаете Java, потому что вы не знаете базовых c соглашений о программировании, таких как

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

Вы также используете прямой доступ к полям из привилегированного аспекта, вместо того, чтобы просто создавать методы getli publi c для поля вашего класса и их использование. Метод toString также полезен, потому что тогда вы можете легко напечатать объект, не обращаясь к геттерам и не создавая собственный вывод.

Кроме того, совет, выполняемый после метода main, является хорошим экспериментом, но не делает имеет смысл. Поскольку владелец учетной записи имеет то же имя, что и один из владельцев учетной записи в вашем приложении, похоже, что вы хотите взломать эту учетную запись. Я прокомментировал код там, чтобы объяснить, почему он не может так работать.

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

package de.scrum_master.app;

public class Account {
  private String owner;
  private double balance;

  public Account(String owner, double balance) {
    this.owner = owner;
    this.balance = balance;
  }

  public void withdraw(double amount) {
    balance -= amount;
  }

  public void deposit(double amount) {
    balance += amount;
  }

  public String getOwner() {
    return owner;
  }

  public double getBalance() {
    return balance;
  }

  @Override
  public String toString() {
    return "Account[owner=" + owner + ", balance=" + balance + "]";
  }

  public static void main(String[] argv) {
    Account bossAccount = new Account("Boss", 2000);
    Account nerdAccount = new Account("Nerd", 1000);
    bossAccount.deposit(400);
    nerdAccount.withdraw(200);
    bossAccount.withdraw(300000);    // Cannot withdraw more than account balance
    nerdAccount.withdraw(-500000);   // Cannot withdraw a negative amount
    bossAccount.deposit(-123456);    // Cannot deposit a negative amount
    System.out.println(bossAccount);
    System.out.println(nerdAccount);
  }
}
package de.scrum_master.aspect;

import de.scrum_master.app.Account;

public aspect AccountAspect {

  // Withdrawal
  void around(Account account, double amount) :
    execution(void Account.withdraw(double)) &&
    target(account) &&
    args(amount)
  {
    if (amount > account.getBalance()) {
      System.out.println("Cannot withdraw more than account balance");
      return;
    }
    if (amount < 0) {
      System.out.println("Cannot withdraw a negative amount");
      return;
    }
    proceed(account, amount);
  }

  // Deposit
  void around(double amount) :
    execution(void Account.deposit(double)) &&
    args(amount)
  {
    if (amount < 0) {
      System.out.println("Cannot deposit a negative amount");
      return;
    }
    proceed(amount);
  }

  // This does not make any sense because
  //   1. it happens after the application ends (after leaving main method)
  //   2. Even though the account owner is the same as in the main method,
  //      it does not mean that by creating a new object with the same name
  //      the "Nerd" can manipulate the original account balance. You have to
  //      intercept the original Account object and manipulate it directly.
  after() : execution(public static void *.main(String[])) {
    System.out.println("--- after end of main program ---");
    Account account = new Account("Nerd", 3000);
    account.deposit(-100);
    System.out.println(account);
  }

  // TODO: PIN secret password
  // TODO: transaction record
}

Журнал консоли будет выглядеть следующим образом:

Cannot withdraw more than account balance
Cannot withdraw a negative amount
Cannot deposit a negative amount
Account[owner=Boss, balance=2400.0]
Account[owner=Nerd, balance=800.0]
--- after end of main program ---
Cannot deposit a negative amount
Account[owner=Nerd, balance=3000.0]

Я не буду выполнять за вас домашнее задание, но дам несколько советов:

  • PIN (секретный) пароль): классу Account необходимо поле pin, которое можно установить в конструкторе, и не должно иметь метода получения publi c, чтобы никто не мог получить доступ к PIN-коду. Если назначение требует, чтобы вы не редактировали базовый класс, а решали проблему через AOP, вы можете использовать определение между типами (ITD), чтобы добавить приватное поле и установщик publi c, возможно, даже дополнительный конструктор к учебный класс. Затем вы добавите совет, в котором пользователю будет предложено ввести PIN-код на консоли, если он впервые попытается получить доступ к каким-либо транзакционным методам, таким как deposit и withdraw определенной учетной записи. После правильного ввода PIN-кода он сможет продолжить, в противном случае появится сообщение об ошибке и транзакция будет запрещена. Сам аспект может хранить кэш (временное хранилище) всех Account объектов - вероятно, вы хотите использовать Set<Account> - которые были успешно аутентифицированы во время сеанса работы, чтобы пользователь не вводил PIN-код. снова для той же учетной записи.

  • Запись транзакции для учетной записи: Опять же, вы можете использовать ITD, чтобы добавить что-то вроде List<TransactionRecord> в качестве поля к Account, инициализировать его с пустым списком, а затем добавьте запись транзакции для каждого пополнения или снятия. Вы также можете сделать это простым для подтверждения своей концепции, не создавая вспомогательный класс TransactionRecord, а просто используя List<Double> для транзакций, записывая положительные суммы для депозитов и отрицательные для снятия. A List<String> с такими элементами, как «депозит 123,45» или «вывод 67,89», также является приемлемой альтернативой. Важно то, что ваш учитель может видеть правильный аспект логики c.

...