Better option to "where to declare actions?(oop)" - oop

Doubt about where to define the actions that are going to act on attributes of one class?
Ex:-Account is a class where we going to define attributes of account like account no,holder name.
As usual Employee(class) of the Bank can add,update(crud) operation on customer's account.
My doubt is in which class we have to define those (crud)actions either in Employee class or in Account class?.
Because these operations are performed by employee in real time.On the other hand,Actions need to act on Account attributes may define in Account class itself,which is the better one?
'Actions need to be performed on attributes ,defined in same class is better' or 'Actions are defined in class with respect to whose actions are they(actors) is better'?

In my understanding of the problem you describe, such "operations" go in the service layer.
You can see in the link I shared above that Martin Fowler describes the service layer as:
Defines an application's boundary with a layer of services that
establishes a set of available operations and coordinates the
application's response in each operation.
So, in my view of your solution, both Employee and Account are just POJOs like #Rotka said. In my view the interfaces for your layers would be somewhat like
At the data source layer:
interface AccountRepository {
Account findById(Long id);
Account save(Account account);
}
And I doubt that you can delete a bank account, you could put it a state of inactivity though.
Than your service layer could be somewhat like
interface AccountService {
Account openAccount(Account account);
void closeAccount(Account account);
transferFunds(Account source, Account target);
...
}
What you call employee is probably the wrong abstraction to use here. You probably think in terms of users, like is the current user allowed to open accounts?
So, consider the following hypothetical implementation
class DefaultAccountService implements AccountService {
private SecurityContext securityContext;
private Validator validator;
private AccountRespotiroy accountRepository;
#Override
public Account openAccount(Account account) {
if(!securityContext.getUser().hasPermission("openAccount")){
throw new UnAuthorizedException("You cannot open accounts");
}
Set<ConstraintViolation> violations = validator.validate(account);
if(violations.size() > 0){
throw new BadRequestException("Invalid account", violations);
}
return accountRepository.save(account);
}
...
}

IMHO , Employee class should be a simple POJO , in order to use it in other components , and you should create an AccountOperation Service (an EJB in Java EE context)
public class AccountOperation
{
Customer customer;
Employee employee;
public void createAnAccount(){
}
public void deleteAnAccount(){
}
public void debitAnAccount(){
}
}

For creating and deleting an account - create an instance of the account, and then pass the "whodunnit" as the employee - or some related identifier when something is done:
Account Account = new Account(Customer, AccountNumber);
Account.createAccount(Employee).
Account.deleteAccount(Employee).
For transactions you need two accounts - the credit and debit account. Because a transaction spans multiple accounts, the following method needs to be in it's own class:
public void AccountTransaction(Account CreditAccount,
Account DebitAccount,
float TransactionAmount.
Employee Employee){
CreditAccount.creditAccount(TransactionAmount, Employee);
DebitAccount.debitAccount(TransactionAmount, Employee);
}
most likely this method would be called by a number of "transaction types" (loan, interest payment, money transfer, etc.)

Related

Business logic and rules - how to decouple them from the domain model

I'm having slight trouble figuring out how to make my design loosely coupled. Specifically how to implement business logic and rules into domain models, as well as where to place the different parts of the code - i.e. folder structure.
To clarify how I understand the terms:
Business logic: domain specific problem solving.
Business rules: domain specific rules.
Domain model: abstractions of domain specific, real world objects e.g. an employee.
So, let's do a simple example
Say we have a company with employees. Every employee must have a security number (business logic). The security number must be at least 10 characters long (business rule).
My shot at modeling this would look something like:
# Conceptual model of an employee within the company
class Employee {
private $name;
private $securityNumber;
// Business logic
public function setSecurityNumber(string $securityNumber,
SecurityNumberValidatorInterface $validator) {
if($validator->validateSecurityNumber($securityNumber)) {
$this->securityNumber = $securityNumber;
} else {
throw new \Execption("Invalid security number");
}
}
}
# Setup interface that corresponds to the business logic
interface SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool;
}
# Time to implement the business logic that is compliant with the rule
class SecurityNumberValidator implements SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool {
$valid = false; // control variable - ensuring we only need a single return statement
$length = strlen($validateThisSecurityNumber);
if ($length < 10) {
$valid = true;
}
return $valid;
}
}
I see some problems with this approach...
Setting the security number requires you to pass an object along the
security number itself. Which I think looks a bit nasty for a setter.
Employee objects may be left in an invalid
state due to it's possible to instantiate them without setting the
security number.
To solve the second problem, I can just create a constructor for the Employee class like the one below
public function __constructor(string $name,
string $securityNumber,
SecurityNumberValidatorInterface $validator) {
$this->name = $name;
$this->setSecurityNumber($securityNumber, $validator);
}
This may be an antipattern due to calling a setter in the constructor...
What is a nicer approach to this? Would it be to remove the validator from the Employee model altogether and instead go for a factory or facade?
Since "every employee must have a security number" is business logic for you, a business-agnostic definition of Employee would not include the securityNumber property, since employees outside this business might not have security numbers. Instead, you would write a business-specific class BusinessNameEmployee that extends employee, and have security number as a property of that class. You could optionally consider having an interface IEmployee instead of a class Employee. Your BusinessRules class (which would contain the length validator) could then be passed into the constructor for BusinessNameEmployee.
There is way call value object, that's part of an entity. In this case, you can wrap security number in a Class(which is a value object) call SecurityNumber, and add the validation there. You can refer to this example: https://kacper.gunia.me/ddd-building-blocks-in-php-value-object/
In DDD, there is a anti-pattern call Primitive Obsession, your mind may be deep in this trap.

Why is there a resource/operation required instead of type/value using claim based auth

Our old software architecture used role based validation. We now want to use claims based authorization. As a matter of fact, I think we always used something modelling claims, even if we used role base technology.
The lowest level are Privileges. A privilege may be "invoke the user service adding a user" or short "UserService.Add". Privileges can be assigned to groups. Users can be members of groups. In the end, through group membership, a user can have a list of privileges.
The old system used a combination of UserNamePasswordValidator, IAuthorizationPolicy and CodeAccessSecurityAttribute to have attributes that were written above the service method and on call of the service method, the validity would be checked. If the user didn't have the required privilege, access would be denied. Worked great.
[CompanyRoleRequired(SecurityAction.Demand, Role = "Common.Connect")]
[CompanyRoleRequired(SecurityAction.Demand, Role = "SomeServiceName.Save")]
public void Save(IEnumerable<Data> data)
{
// code
}
Now I'd like to use claims based authorization. Keeping the model above, I would create either a claim for each former privilege, or maybe a claim for each service with valid values of it's operations. For example, instead of "UserService.Add" I could add a claim "UserService" and people with the former privilege would get the claim with the value "Add". I would like to offer the service developers the same ease of access checking, so I'd like the required claims to be annotated above the service method. Microsoft already provides a ClaimsPrincipalPermissionAttribute for this.
Instead of implementing IAuthorizationPolicy, I implemented ClaimsAuthorizationManager.
Question 1) The authorization manager gets called twice. Once with the soap url and once with my attribute. I've googled a lot and it seems to be by design. I don't have a problem differentiating between the calls and checking only my calls, but maybe I didn't see something. Is there an option or an easy way to not get called on soap calls with the urls and only getting called for the attributes?
Question 2) The access check offers the ability to check if the pricipal has a claim. Obviously, a claim has a type/name and a value. I would have expected the attribute to offer such an interface. However, the attribute wants to know about the resource and operation. The access check function I need to overwrite also needs to check resources and operations. Why is that? Do I need to map resource/operation to claims in my AuthorizationManager? And if I don't see any need for it, would it be ok to just put the expected type and value of the claim in the attribute as resource and operation and map them 1:1 in the authorization manager? Or do I miss out on some important security feature if I do this?
Q1) That's unfortunately the case - and since both the "automatic" calls and the attribute/.CheckAccess use the same claim types you cannot easily distinguish between the two. I wrote about that here: http://leastprivilege.com/2011/04/30/what-i-dont-like-about-wifs-claims-based-authorization/
Q2) You are missing the concept here. The idea is to NOT check for specific claims - but to rather annotate the code with "what you are doing". The person that writes the business code typically does not know exactly who is allowed to call it (or which claims are exactly needed). You only tell the authZ poliy that you are about to add a customer (as an example). The authorization manager's job is to figure out if the principal is authorized to do that (by whatever means). Separation of concerns. See here: http://leastprivilege.com/2011/04/30/what-i-like-about-wifs-claims-based-authorization/
Not sure if this is going to be helpful to you but ClaimsAuthorizationManager has method that can be overridden (LoadCustomConfiguration) that you can use to load your policy from XML file. That policy might be designed in a way to allow mapping between resources and actions and roles. I've built in-code access control list instead that looks like this:
public interface IAccessControlList
{
List<CustomAccessRule> Rules { get; }
}
public class CustomAccessRule
{
public string Operation { get; set; }
public List<string> Roles { get; set; }
public CustomAccessRule(string operation, params string[] roles)
{
Operation = operation;
Roles = roles.ToList();
}
}
My claims authorization manager looks like this:
public class CustomClaimsAuthorizationManager : ClaimsAuthorizationManager
{
private IAccessControlList _accessControlList;
public CustomClaimsAuthorizationManager(IAccessControlList accessControlList)
{
_accessControlList = accessControlList;
}
public override bool CheckAccess(AuthorizationContext context)
{
string operation = context.Action.First().Value.Split('/').Last();
CustomAccessRule rule = _accessControlList.Rules.FirstOrDefault(x => x.Operation == operation);
if (rule == null) return true;
if (context.Principal.Identities.First().IsInRoles(rule.Roles)) return true;
throw new MessageSecurityException(string.Format("Username {0} does not have access to operation {1}.", context.Principal.Identities.First().Name, operation));
}
}
And here is an example of one access control list implementation for one service:
public class SampleServiceACL : IAccessControlList
{
public List<CustomAccessRule> Rules { get; private set; }
public SampleServiceACL()
{
Rules = new List<CustomAccessRule>();
Rules.Add(new CustomAccessRule("OpenAccount", "Manager", "Owner"));
Rules.Add(new CustomAccessRule("CloseAccount", "Manager", "Owner"));
Rules.Add(new CustomAccessRule("SendEmail", "User", "Manager", "Owner"));
}
}
And I'm applying this at service host base level by using:
protected override void OnOpening()
{
base.OnOpening();
IdentityConfiguration identityConfiguration = new IdentityConfiguration();
identityConfiguration.SecurityTokenHandlers.Clear();
identityConfiguration.ClaimsAuthorizationManager = new CustomClaimsAuthorizationManager(new SampleServiceACL());
this.Credentials.IdentityConfiguration = identityConfiguration;
...
}
As a result, I'm not using attributes at all, all authorization logic is centralized in claims authorization manager over ACL.
Now if you don't like this approach, and you're still in pursuit of attribute that will check for specific claims, you can then derive from CodeAccessSecurityAttribute and actually implement that logic. What is given by MS out of the box is good, but it does not mean you should stick to it by any means. Also logic for checking the claims can be implemented as an extension to identity, i.e.:
public static class IdentityExtensions
{
public static bool IsInRoles(this ClaimsIdentity id, List<string> roles)
{
foreach (string role in roles)
if (id.HasClaim(ClaimTypes.Role, role)) return true;
return false;
}
}
So you might build extensions, custom attribute, and then use extensions in the attribute to perform your validation logic.
Again, this is just something that I've already done. Might not be what you're looking for but it's one type of custom solution.

Complex inheritance scenario

Let's say you need to build an application that manages cheques. Each cheque contains data about the amount of money, the date, the payee and an additional payment date which may or may not be present. Additionally, each cheque must be related to a current account which belongs to a certain bank.
Now, our application should allow cheques printing under these conditions:
Each bank managed by the app has a different cheque layout (i.e. each field has a different x,y position).
The cheque layout changes slightly if the payment date is present, even with the same related bank object. But, from bank to bank these changes may not be the same (e.g. bank A may vary position for the date field, while bank B changes position for the payee field)
With these restrictions in place, it's difficult to come up with a simple inheritance schema as there is no consistent behavior to factor out accross the different types of cheques there are. One possible solution would be to avoid inheritance and create a class for every cheque - bank combination:
class ChequeNoPaymentDateForBankA
class ChequeWithPaymentDateForBankA
class ChequeNoPaymentDateForBankB
class ChequeWithPaymentDateForBankB, etc.
Each of these classes implement the print() method which takes the fields positions from a Bank object and builds up the cheque layout. So far so good, but this approach leaves me with a strange feeling as there is no room for code reuse. I wonder if I'm misinterpreting the problem and perhaps there is a better way. As this is not a new problem domain at all, I'm sure this is a reinvent-the-wheel effort. Any insights will be kindly appreciated.
Usually in these situations I move from inheritance to delegation. That is, instead of putting the common code in a superclass (which, as you say, is problematic becuase there are two dimensions), I put the common in a field (one field per dimension) and delegate to that field.
Assuming you're speaking about Java:
public interface Bank {
public void print();
}
public class BankA implements Bank {
public void print() { ... }
}
public class BankB implements Bank {
public void print() { ... }
}
public interface PaymentSchedule {
public void print();
}
public class WithPaymentDate implements PaymentSchedule {
public void print() { ... }
}
public class NoPaymentDate implements PaymentSchedule {
public void print() { ... }
}
public class Cheque {
private final Bank bank;
private final PaymentSchedule schedule;
public Cheque(Bank b, PaymentSchedule s) {
bank = b;
schedule = s;
}
public void print() {
bank.print();
schedule.print();
}
}
That's the general structure of the solution.
Depending on the exact details of your print() algorithm you may need to pass some more data into the print methods and/or to pass this data into the constructors of the classes (of the Bank or PaymentSchedule subclasses) and store it in fields.
I would start by separating the domain model (cheques, banks, etc) from the view (the way the cheques are printed). This is the basic idea behind the MVC pattern and one of its aims is to allow the same domain model to be displayed in different ways (which seems to be your case). So, I would first create the domain classes, something like:
class Cheque
{
protected $bank;
protected $money;
...
}
class Bank {...}
Note that these classes are the "M" of the MVC triad and implement the logic of your domain model, not the behavior related to the rendering process. The next step would be to implement the View classes used to render a cheque. Which approach to take heavily depends on how complex your rendering is, but I would start by having a ChequeView class that renders the common parts and that delegates to other sub-view the specific parts that can change (in this case the date):
abstract class ChequeView
{
protected $cheque;
protected $dateView;
public function __construct($cheque)
{
$this->cheque = $cheque;
$this->dateView = //Whatever process you use to decide if the payment date is shown or not
}
public function render()
{
$this->coreRender();
$this->dateView->render();
}
abstract protected function coreRender();
}
class BankACheckView extends ChequeView
{
protected function coreRender() {...}
}
class BankBCheckView extends ChequeView
{
protected function coreRender() {...}
}
abstract class DateView
{
abstract function render()
}
class ShowDateView extends DateView
{
function render() {...}
}
class NullDateView extends DateView
{
function render() {...}
}
And, if there is code to reuse across subclasses, you can of course factor them in ChequeView and make coreRender() call them.
In case your rendering turns to be too complex, this design may not scale. In that case I would go for splitting your view in meaningful subparts (e.g. HeaderView, AmountView, etc) so that rendering a cheque becomes basically rendering its different sub-parts. In this case the ChequeView may end basically working as a Composite. Finally, if you reach this case and setting up the ChequeView turns out to be a complex task you may want to use a Builder.
Edit based on the OP comments
The Builder is mostly used when the instantiation of the final object is a complex process (e.g. there are many things to sync between the sub-parts in order to get a consistent whole). There is generally one builder class and different clients, that send messages (potentially in different orders and with different arguments) to create a variety of final objects. So, while not prohibited, it is not usual to have one builder per type of object that you want to build.
If you are looking for a class that represents the creation of a particular instance you may want to check the Factory family of patterns (maybe the Abstract Factory resembles closely to what you had in mind).
HTH

Advise on object-oriented design

I would like some help with a OOD query.
Say I have the following Customer class:
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
It's a simple placeholder for customer related data. Next comes the CustomerFactory, which is used to fetch customers:
public static class CustomerFactory
{
public static Customer GetCustomer(int id)
{
return null; // Pretend this goes off to get a customer.
}
}
Now, if I wanted to write a routine named UpdateCustomer(Customer customer) can someone suggest where I could place this method?
Obviously I don't want to use the Customer class since that would be against SRP (Single Responsibility Principle), also I don't see it as a good idea to attach the method to the CustomerFactory class, since it's only role is to get customers from the database.
So it looks like I'm going to need another class, but I don't know what to name it.
Cheers.
Jas.
What you have called a Factory isn't a Factory at all. It's a Repository.
A Factory handles the instansiation of various classes sharing a common Interface or Class Hierarchy based on some set of parameters.
A Repository handles the retrieval and management of data.
The Repository would definitely have the UpdateCustomer(Customer customer) method in it as well as the GetCustomer(int id) method.
You are more on less on your way to creating a Repository. Do something like this:
public interface ICustomerRepository
{
Customer SelectCustomer(int id);
void UpdateCustomer(Customer customer);
void DeleteCustomer(int id);
void CreateCustomer(Customer customer);
}
Then create concrete implementations of this interface (the interface is really just because it's good practice to program against interfaces - you could skip it, though, although I would recommend that you keep it).
Wouldn't your UpdateCustomer routine be placed in your DAL (Data Access Layer). You should define a class to handle inserts or updates to the database and then pass a customer object to it.
You could write the DAL class to handle all of this but I don't see any issue in storing it in your CustomerFactory class, although as mentioned it is not really a factory.

Data Access Layer and Business Objects

Not sure if I have the correct terminology, but I am a little confused on how to set up my 3-tier system.
Lets say I have a table of Users in my DB.
In my DAL, I have a UserDB class that calls stored procs into he DB to insert, update, delete.
I also have a UserDetails class that is used in UserDB to return and pass in objects.
So now I am not sure how to use this in my Business Logic Layer. Do I need another BLL object class for users? If so, would this not be redundant?
Or do I just use the UserDetails class throughout my BLL?
Look up a concept called 'Domain Driven Design' - the biggest thing there is using what's called a repository pattern (such as your UserDB class) as an adapter to the database, as well as a factory. Your business objects, or domain objects, then incorporate business logic into themselves and can handle interactions with other business objects.
What technology are you using? Something like ActiveRecord can probably help you a lot.
You typically would enforce Business Rules in your BLL. For example, you might allow regular call center employees to offer a 10% discount on new service but allow a manager to offer a 20% discount. You would have a business rule in your BLL that goes something like:
// Pseodocode
double Discount
{
set
{
if (value > 10% AND Employee Is Not Manager) then throw Exception
if (value > 20%) then throw Exception
discount = value;
}
}
You can use following design:
DAL:
namespace DAL.Repository
{
public class UsersRepository
{
public static IList GetUser(string UserId)
{
using(MyDBEntities context=new MyDBEntities())
{
// it calls SP in DB thru EF to fetch data
//here you can also context.user to fetch data instead of SP
return context.GetUser(UserId).ToList();
}
}
}
}
BLL
namespace BLL
{
public class User
{
public static IList GetUser(string UserId)
{
return DAL.Repository.UserRepository.GetUser(UserId);
}
}
}
PL
ddlUser.DataTextField = "UserName";
ddlUser.DataValueField = "UserId";
ddlUser.DataSource= BLL.User.GetUser(string.Empty);
ddlUser.DataBind()
Note: while sending data from BL to PL converting DB Entity to Business entity is required if you want to loop thu data in PL.