Criando um processador de carteiras em C++ - Dia 02: O primeiro commit
Olá pessoal :D Recentemente decidi me aventurar num projetinho pessoal para ampliar meu portfolio de backend: criar um processador de carteiras em C++. Para documentar e compartilhar todo esse processo, vou todos os dias escrever um artigo curto relatando o que fiz e adicionando considerações importantes em cada etapa do processo.
O código do processador ficará aberto à todos através deste link. Quem quiser acompanhar mais de perto e quem sabe até colaborar com o projeto, pode ficar à vontade para dar follow, fork ou stars no repositório.
Aprendendo a programar em C++
Acho que algo importante que deixei de comentar no artigo do dia 01 é que eu nunca programei em C++ :D
Aí você me pergunta... então por que raios você escolheu C++ como a stack principal do seu projeto? A resposta é simples: Pelo desafio e porque considero C++ a linguagem mais apropriada para os meus objetivos iniciais. C++ é uma linguagem muito leve e muito performática, têm tipagem estática e me permite controlar com certa precisão todos os meus cálculos. Era exatamente isso que eu precisava: um sistema eficiente e sólido em termos de cálculos financeiros e contratos de entrada e saída.
Preciso admitir que não parti do zero. Como contei aqui neste artigo no último mês mergulhei de cabeça na linguagem C, o que me deu uma boa base inicial para aprender C++.
Comecei os estudos com o curso do Codacademy, mas logo ele ficou bastante entediante e repetindo coisas que eu já sabia. Então optei pelo método clássico: entrei no w3schools e fui passando página por página, conhecendo a semântica da linguagem.
Aqui vai um comentário importante sobre fazer projetos novos em linguagens que você não conhece: o que muda entre a maioria das linguagens é principalmente a semântica, ou seja, o jeito como se escrevem as funções, loops, condicionais, etc. A lógica da programação continua a mesma quase sempre. Alguns detalhes sobre a linguagem em específico podem ser importantes (saber como a linguagem faz a alocação de memória, quais são seus data types e como são implementados, se é possível fazer programação assíncrona, etc), mas eles não te impedem de começar um novo projeto. Essas são coisas que a gente aprende com o uso da linguagem no dia a dia.
Meu primeiro commit
Por fim, depois de aprender como escrever classes, funções e tudo mais em C++, coloquei de fato a mão na massa. Meu primeiro trabalho foi definir a arquitetura do meu sistema. Optei por dividir em módulos. Inicialmente um para as carteiras e outro para as transações.
No meio do caminho, vi que não existia nenhum package de terceiros que implementava as melhores práticas em cálculos financeiros. Então também criei um módulo money onde eu mesma farei essa implementação.
Dessa forma, ficou assim minha estrutura de pastas:
Dentro de cada um desses módulos, criei um arquivo .h que é a extensão de arquivos de interface em C e C++. Nelas, defini as minhas classes, seus métodos e propriedades, de acordo com o benchmarking que fiz ontem. As interfaces ficaram assim:
// money.h
#include <string>
using namespace std;
class Money {
public:
int amount;
int precision;
void add(Money money);
void subtract(Money money);
void multiply(Money money);
void divide(Money money);
void toUnit();
};
// transaction.h
#include <string>
using namespace std;
enum TransactionType {
INCOME = 'INCOME',
EXPENSE = 'EXPENSE',
};
struct UserBalance {
double balance;
};
struct WalletBalance {
string wallet_name;
double balance;
};
struct TypeBalance {
TransactionType transaction_type;
double balance;
};
struct CategoryBalance {
string category_name;
double balance;
};
class Transaction {
public:
double amount;
TransactionType type;
bool completed;
string time;
string category;
string wallet;
bool ignore;
static UserBalance getUserBalance(Transaction transactions[]);
static WalletBalance getWalletBalance(Transaction transactions[]);
static TypeBalance getTypeBalance(Transaction transactions[]);
static CategoryBalance getCategoryBalance(Transaction transactions[]);
};
// wallet.h
#include <string>
#include "transaction/transaction.h"
using namespace std;
class Wallet {
public:
string name;
double initial_balance;
double current_balance;
void addTransaction(Transaction transaction);
void removeTransaction(Transaction transaction);
};
Conclusão
Por hoje, foi isso. Acho que o próximo passo é melhorar essas interfaces, populando com mais métodos e adicionando a documentação de cada propriedade e função através dos comentários. Veja aqui mais sobre API docs de projetos em C++.
Além disso, amanhã já devo poder começar a escrever a lógica das funções previamente definidas. Um desafio, é entender como é a melhor forma de fazer nossa aplicação consumir dados e fazer um parser para inicializar nossas classes a partir deles.