Where to put classes with a complex logic

Hello!

I’m developing a web application that will simulate personal finance for a family. In a simplified way it will simulate cash flow, checking account, investments on a financial market, inflation, insurance etc.

I’ve already developed some basic PHP classes from the scratch to perform the functionality demonstration for other members of our team. Now I’m about to start with the development of UI and real data scheme for the simulation.

I’ve chosen a Yii framework which seem pretty amazing to me! Yet I’ve no experience with PHP frameworks so far (I just did some coding in Visual C# in the past). After reading Yii tutorials and guides I think I have a basic idea about Yii concepts. I’m just not sure where to put the classes with the main simulation logic. Most of the simulation objects are not stored in the database yet from the MVC point of view they should belong to model. To not to begin the development at the wrong end I’d like to ask you for some hints.

Let me give you a brief overview of some of the basic classes/interfaces that are part of the simulation:

  • class Simulation - Loads and stores all components of the simulation.

  • class PeriodicalActivityController - Keeps record of all objects that do something on a monthly basis and calls onNextMonth() method of these objects.

  • interface IPeriodicallyActive - Interface for objects with onNextMonth() method.

  • interface IValuable - Interface for objects that could be valued in dollars by getValue() method.

  • class Family implements IPeriodicallyActive - Definition of income, expenses, etc.

  • class Portfolio implements IValuable - Holds financial products (securities, insurance, etc.), specifies checking account etc.

  • class Security implements IValuable, IPeriodicallyActive - Securities defined by Quantity and Price, could be purchased or sold, pays dividend or interest.

  • class Maket implements IPeriodicallyActive - Holds market prices for securities.

  • class PortfolioManagement implements IPeriodicallyActive - Class that executes purchase/sell orders according to the specified allocation. It also runs automatic investments.

There is more but these should be sufficient to give you an idea about the design of the simulation. There will two major ways of how the Simulation is used:

  1. The first one is that user sets the portfolio allocation (percentage of stocks/bonds/cash) and clicks on “Next Month/Year” and the Simulation takes this instruction and moves to the next month or repeats itself as many times as the user doesn’t make any change to the portfolio allocation.

  2. The other one is the automatic run in which the portfolio allocation is adjusted by the automatic strategy. This should serve as a benchmark to which the user’s strategy is compared.

Basic inputs and outputs of each round will be stored to DB (and loaded from it) however the rest of the Simulation classes are quite independent.

Would you have any suggestions how to fit these simulation classes into the Yii framework? Or just let me know, please, if you know about any similar open source Yii app that I could get inspired from.

Thank you!

General rules:

  1. Controllers: Are used to react to user input, instantiating models of any kind and to render the appropriate views.

  2. Models: Can either extend CActiveRecord if they are directly related to a table in your DB or they can extend CModel if they are not related to a db table. They hold all the business logic + CRUD parts (if extending CActiveRecord)

  3. Components: If you want to reuse some parts of your code that doesn’t really fit into a model nor a controller you could make use of components. Imagine a thumbnail creator. You wouldn’t create a model for that and putting the code in each controller that is using it could mean a lot of duplicated code. In a case like that you want easy access to the code within all parts of your app with a syntax like “Yii::app()->thumbnail->fromFile(‘someFile.jpg’)” to keep things simple. A component enables you to do exactly that (extending either CComponent or CApplicationComponent).

  4. Views: Well, I guess you know what they are doing

  5. Widgets: There could be some code in your views that either contains too much logic or that you want to reuse in other views. That’s what widgets are there for. In your case some of the parts that output financial statistics etc. could be an example for a widget.

So to sum things up: It is impossible to give you a "do it like that and you are right" guide as you can do things in different ways. Put most of your logic into models, keep the controllers and views as slim as possible, put reusable code that directly interacts with the user into widgets and make use of components to reuse pure backend-stuff like thumbnail creation etc. There are edge cases of course but this should give you a good overview

Hope it helps,

Hannes

Thank you Hannes for your comprehensive answer!

I’ll probably make the main Simulation class to extend CComponent. Later I’ll think about how to redesign inner classes. I’ll also consider a replacement of my PeriodicalActivity structure by the implementation of Yii events. Yet I’ll have to explore it a bit more thoroughly.

That’s a good idea to use widgets for statistics etc. There will be plenty of those.

Thanks,

Vojtech