I have an app that is essentially a wrapper for a 3rd party API. The app does not use a database and only stores a single cookie which is the session ID that the API requires.
The API is a shopping system which allows users to
-login/register/edit profile/logout
-buy merchandise
-make a donation
-become a member
The API has 50 or so methods that my app needs to connect to. Example API calls are addItemToBasket(), addDonation(), GetUserDetails() etc.
I am trying to work out what should be classes in my application. Here is what I have so far:
Classes
1) APIManager() Class Contains the methods that match one-to-one with the methods exposed in the 3rd party API and provides the mechanism to make a connection to the remote API server. So a user would be logged in via
APIManager->loginUser($sessionKey, $uid, $pwd);
and the remote API would set the user as logged in. If needs be, my app can check the logged in status of any session key by calling the API:
APIManager->isLoggedIn($sessionKey);
2) User() Class This holds methods that contain business logic required before processing API calls such as Register or Login. An example method is:
function login($_POST) {
//perform sanity checks, apply business rules etc.
//if certain conditions are met, we may pass in a promo code, $pc
APIManager->loginUser($sessionkey, $_POST['uid'], $_POST['pwd'], $pc);
}
I realise that I could probably just make a call to APIManager from the login page, rather than having a User class per se, but I felt that since some business logic needs to run before we actually call the API's loginUser() method, it felt right to have that handled within a User class. I'd be keen to know what people think about this.
3) Basket() Class
The basket is managed in the 3rd Party API, so my app's role is to make the appropriate API calls to add new items to the basket, remove items, view the basket etc. My app knows nothing about the basket until the data is retrieved from the API, nor can it make any changes to the basket without going via the API. Again, it felt appropriate to group this related logic into a Basket class. The front end web page might call something like:
Basket->addItem(23);
and this addItem() method in the Basket class would looks something like:
addItem($itemID) {
//perform checks, apply business rules e.g. if user is eligible for discount
APIManager->addToCart($itemID, $discount);
}
where addToCart() is the third party API method we call to process the item.
4) Donation() Class
This allows users to make a donation. The donation appears in the basket and can be removed from the basket. I thought of just adding an addDonate() method to the Basket class and not worry about having a Donation object at all, but... (see below)
5) Membership() Class
... memberships are actually a type of donation! The API will treat donation going into a certain account as being a 1 year membership, and not a plain donation. We cannot change the logic/behaviour of the 3rd party API.
So, if I donate $50 to account '1' then it's just a normal donation, but if I donate $100 to account '8' then I become a member with all the member benefits (reduced prices, no postage fee etc).
Here's where I'm not sure of the best way to design this.
Should I create a Donation class and then extend that with Membership, since all of the Donation methods will be required by Membership. But Membership will need additional methods such as renew() or getExpiry() etc.
Also, should I look at extending User to become Member? Again, a member has all of the core methods that User has, but also has additional ones such as getSpecialOffers() or getDiscountCode() that only members would access.
Any guidance in how to best approach the design would be very much appreciated.
Thanks, James