Imagine an application where you have a class named Transaction representing a financial transaction.
These transactions can be classified based on the value of properties of Transaction class and some business rules.
An enum called TransactionType represents the possible value of such a classification: Type1Transaction, Type2Transaction, NotRelevant.
Type1Transactions and Type2Transactions will be reported because they are somewhat suspicious, NotRelevant transactions won't be reported.
This kind of classification is interesting only in order to report transaction and does not represent an intrinsic property of Transaction class (that's why Transaction class does not have a property representing this classification).
Well, at this point we want to write a class whose responsibility is determine the classification given a transaction, let's call it TransactionClassificator.
Its interface expose a method GetTransactionType() whose return value is TransactionType.
The most obvious implementation is as follows:
public TransactionType GetTransactionType()
{
if(IsType1Transaction())
return TransactionType.Type1Transaction;
if(IsType2Transaction())
return TransactionType.Type2Transaction;
return TransactionType.NotRelevant;
}
This method clearly violates OCP principle: it is NOT closed to modifications because it must be modified every time a new value for enum TransactionType will be introduced. I can't figure out how to use abstraction to remedy to OCP principle violation in this specific scenario.
Thanks for helping.
Enrico
Use a TypeReporter (or some more suitable name). It's responsibility will be to determine the transaction type based on the data it gets from Transaction:
interface TypeReporter {
/**
* Methods required for transaction to feed the data required for the
* business rules to determine the transacion type
*/
public TransactionType determineType();
}
Now the transaction can report its own type with TypeReporter's help:
interface Transaction {
/** among other things **/
public TransactionType reportType(TypeReporter reporter);
}
e.g.
class ConcreteTransaction implements Transaction {
public TransactionType reportType(TypeReporter reporter) {
reporter.hereIsThis(someProperty);
reporter.andThat(someOtherProperty);
return reporter.determineType();
}
}
So Transaction delegates the type determination to another object. That way it is closed for modification if a new type or a new strategy for determining the type arises. If that happens you write a new TypeReporter.
Edit:
To make the method for determining type more change resistant you can keep the conveniently named types like so:
public enum TransactionType {
Type1Transaction,
Type2Transaction,
NotRelevant
}
where method that returns the type can be:
public TransactionType determineType() {
//business logic to determine the type goes here
//represent that type as a string (String determinedType)
//now we check if that string is a valid enum value, if not returning NotRelevant
try {
return Choices.valueOf(determinedType + "Transaction");
} catch (IllegalArgumentException ex) {
return TransactionType.NotRelevant;
}
}
This way if the TransactionType becomes relevant you can just add it as a new TransactionType value and it will no longer return the NotRelevant.
Related
Every time I google instanceof and casting I will always see answers saying to avoid it and use X pattern.
I have an example where I can't see any pattern I think I could use.
We have 2 classes: Order and Payment (CashPayment and CardPayment).
CashPayment has 1 property called amount and and an implemented method pay.
CardPayment has 1 property called cardNumber and an implemented pay that calls 3rd party API.
Now say you would like to compose a view about an Order, how would someone avoid using instanceof or casting here to show the payment details?
With instanceof I can do this:
order = new Order(...);
order.checkout(aPayment);
Payment Details (Cash):
Type: (instanceof CashPayment ? "Cash") or order.payment().type();
Amount: ((CashPayment) order.payment()).amount();
Payment Details (Card):
Type: (instanceof CardPayment ? "Card") or order.payment().type();
Card Number: ((CardPayment) order.payment()).cardNumber();
Question: can we really avoid instanceof and casting? If yes, how can we achieve this the "OO-way"? If no, I assume this is one of the valid cases?
IMO, we can avoid instanceof/casting and favor use of overridden methods however if you want to know about a concrete object it can't be avoided.
Edit:
I am trying to write my Domain Models which means it is agnostic of infrastructure and application specific stuff.
Imagine we would need to save the Order thru OrderRepository and the Payment has their own tables. Wouldn't it be ugly if it was like:
class OrderRepository {
public function save(Order order) {
// Insert into order query here...
// Insert into orderItems query here...
// Insert payment into its table
queryBuilder
.table(order.payment().tableName())
.insert([
order.payment().columnName() => order.payment().value()
]);
}
}
If you absolutely want to segregate the operation from the object itself (e.g. to maintain separation of concerns), but the operation is strongly coupled to subclass details then you only have two choices.
You either need to rethink the model and find an homogeneous abstraction, which could be any approach that allows you to treat the various types the same way.
e.g.
Payment Details:
Type: {{payment.type}}
{{for attr in payment.attributes}}
{{attr.name}}: {{attr.value}}
{{/}}
or you need to perform some kind of type matching, whether you are using the visitor pattern, pattern matching, instanceof, etc.
e.g. with the Visitor Pattern
interface IPaymentVisitor {
public void visit(CashPayment payment);
public void visit(CardPayment payment);
}
class PaymentRenderer implements IPaymentVisitor ...
class CashPayment extends Payment {
...
public void visit(IPaymentVisitor visitor) {
visitor.visit(this);
}
}
var renderer = new PaymentRenderer(outputStream);
payment.accept(renderer);
The obvious object-oriented solution is to add a display() method to the Payment.
In general instanceof/casting is frowned upon, because it usually indicates a less then optimal design. The only time where it is allowed is when the type-system is not powerful enough to express something. I encountered a few situations in Java where there is no better solution (mostly because there are no read-only collections in Java, therefore the generic parameter is invariant), none in Scala or Haskell yet.
You could go with composition over inheritance.
Perhaps something along the lines of:
public class Payment
{
private CardPaymentDetail _cardPaymentDetail;
public PaymentType Type { get; private set; }
public decimal Amount { get; }
private Payment(decimal amount)
{
// > 0 guard
Amount = amount;
}
private Payment(decimal amount, CardPaymentDetail cardPayment)
: this(amout)
{
// null guard
CardPayment = cardPayment;
}
public CardPaymentDetail CardPayment
{
get
{
if (Type != PaymentType.Card)
{
throw new InvalidOperationException("This is not a card payment.");
}
return _cardPaymentDetail;
}
}
}
IMHO persistence may also be easier. Along the same lines I have also used what equates to an Unknown payment type as the default and then have a method to specify the type: AsCard(CardPaymentDetail cardPayment) { }.
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.
Let's say I have a class Order. An Order can be finished by calling Order.finish() method. Internally, when an Order is finished, a finishing date is set:
Order.java
public void finish() {
finishingDate = new Date();
}
In the application's business logic, there is no need to expose an Order's finishingDate, so it is a private field without a getter.
Imagine that after finishing an Order, I want to update it in a database. For instance, I could have a DAO with an update method:
OrderDao.java
public void update(Order order) {
//UPDATE FROM ORDERS SET ...
}
In that method, I need the internal state of the Order, in order to update the table fields. But I said before that there is no need in my business logic to expose Order's finishingDate field.
If I add a Order.getFinishingDate() method:
I'm changing the contract of Order class without adding business value, ubt for "technical" reasons (an UPDATE in a database)
I'm violating the principle of encapsulation of object oriented programming, since I'm exposing internal state.
How do you solve this? Do you consider adding getters (like "entity" classes in ORM do) is acceptable?
I have seen a different approach where class itself (implementation) knows even how to persist itself. Something like this (very naive example, it's just for the question):
public interface Order {
void finish();
boolean isFinished();
}
public class DbOrder implements Order {
private final int id;
private final Database db;
//ctor. An implementation of Database is injected
#Override
public void finish() {
db.update("ORDERS", "FINISHING_DATE", new Date(), "ID=" + id);
}
#Override
public boolean isFinished() {
Date finishingDate = db.select("ORDERS", "FINISHING_DATE", "ID=" + id);
return finishingDate != null;
}
}
public interface Database {
void update(String table, String columnName, Object newValue, String whereClause);
void select(String table, String columnName, String whereClause);
}
Apart from the performance issues (actually, it can be cached or something), I like this approach but it forces us to mock many things when testing, since all the logic is not "in-memory". I mean, the required data to "execute" the logic under test is not just a field in memory, but it's provided by an external component: in this case, the Database.
This is an excellent observation in my opinion. No, I don't consider adding any methods just for technical reasons acceptable, especially getters. I must admit however, that the majority of people I've worked with would just add the getters and would not think about it in detail as you do.
Ok, so how do we solve the problem of persisting something we can't get access to? Well, just ask the object to persist itself.
You can have a persist() (or whatever) method on the object itself. This is ok, since it is part of the business. If it is not, think about what is. Is it sendToBackend() maybe? This does not mean you have to put the details of persistence into the object!
The method itself can be as removed from actual persistence as you like. You can give it interfaces as parameters, or it can return some other object that can be used further down the line.
See these other answers about the same problems for presentation:
Returning a Data Structure to Display information
Encapsulation and Getters
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
Say I have a common pattern with a Customer object and a SalesOrder object. I have corresponding SalesOrderContract and CustomerContract objects that are similar, flatter objects used to serialize through a web service
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; }
public Address ShippingAddress { get; set; }
//more fields...
}
public class Order
{
public int OrderId { get; set; }
public Customer Customer { get; set;
// etc
}
And my sales order contract looks like this
public class OrderContract
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
}
public class OrderTranslator
{
public static Order ToOrder(OrderContract contract)
{
return new Order { OrderId = contract.OrderId };
// just translate customer id or populate entire Customer object
}
}
I have a layer inbetween the service layer and business object layer that translates between the two. My question is this...do I populate the Order.Customer object on the other end since the Order table just needs the customer id. I don't carry the entire customer object in the OrderContract because it's not necessary and too heavy. But, as part of saving it, I have to validate that it's indeed a valid customer. I can do a few things
Populate the Order.Customer object completely based on the CustomerId when I translate between contract and entity.. This would require calling the CustomerRepository in a helper class that translates between entities and contracts. Doesn't feel right to me. Translator should really just be data mapping.
Create a domain service for each group of operations that performs the validation needed without populating the Order.Customer. This service would pull the Customer object based on Order.CustomerId and check to see if it's valid. Not sure on this because a sales order should be able to validate itself, but it's also not explicitly dealing with Orders as it also deals with Customers so maybe a domain service?
Create a seperate property Order.CustomerId and lazy load the customer object based on this.
Populate Order.Customer in from a factory class. Right now my factory classes are just for loading from database. I'm not really loading from datacontracts, but maybe it makes sense?
So the question is two part...if you have association properties in your enties that will be required to tell if something is completely valid before saving, do you just populate them? If you do, where you do actually do that because the contract/entity translator feels wrong?
The bottom line is that I need to be able to do something like
if (order.Customer == null || !order.Customer.IsActive)
{
//do something
}
The question is where does it make sense to do this? In reality my Order object has a lot of child entities required for validation and I don't want things to become bloated. This is why I'm considering making domain services to encapsulate validation since it's such a huge operation in my particular case (several hundred weird rules). But I also don't want to remove all logic making my objects just properties. Finding the balance is tough.
Hope that makes sense. If more background is required, let me know.
You have a couple of things going on here. I think part of the issue is mainly how you appear to have arranged your Translator class. Remember, for an entity, the whole concept is based on instance identity. So a Translator for an entity should not return a new object, it should return the correct instance of the object. That typically means you have to supply it with that instance in the first place.
It is perhaps useful to think in terms of updates vs creating a new object.
For an update the way I would structure this operation is as follows: I would have the web service that the application calls to get and return the contract objects. This web service calls both repositories and Translators to do it's work. The validation stays on the domain object.
In code an update would look something like the following.
Web Service:
[WebService]
public class OrderService
{
[WebMethod]
public void UpdateOrder(OrderContract orderContract)
{
OrderRepository orderRepository = new OrderRepository(_session);
// The key point here is we get the actual order itself
// and so Customer and all other objects are already either populated
// or available for lazy loading.
Order order = orderRepository.GetOrderByOrderContract(orderContract);
// The translator uses the OrderContract to update attribute fields on
// the actual Order instance we need.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the specific order instance with any properties updated
// so we can validate and then persist.
if (order.Validate())
{
orderRepository.Update(order);
}
else
{
// Whatever
}
}
}
Translator:
public static class OrderTranslator
{
public static void OrderContractToOrder(ref Order order, OrderContract orderContract)
{
// Here we update properties on the actual order instance passed in
// instead of creating a new Order instance.
order.SetSomeProperty(orderContract.SomeProperty);
// ... etc.
}
}
The key concept here is because we have an entity, we are getting the actual Order, the instance of the entity, and then using the translator to update attributes instead of creating a new Order instance. Because we are getting the original Order, not creating a new instance, presumably we can have all the associations either populated or populated by lazy load. We do not have to recreate any associations from an OrderContract so the issue goes away.
I think the other part of the issue may be your understanding of how a factory is designed. It is true that for entities a Factory may not set all the possible attributes - the method could become hopelessly complex if it did.
But what a factory is supposed to do is create all the associations for a new object so that the new object returned is in a valid state in terms of being a full and valid aggregate. Then the caller can set all the other various and sundry "simple" attributes.
Anytime you have a Factory you have to make decisions about what parameters to pass in. Maybe in this case the web service gets the actual Customer and passes it to the factory as a parameter. Or Maybe the web service passes in an Id and the factory is responsible for getting the actual Customer instance. It will vary by specific situation but in any case, however it gets the other objects required, a factory should return at minimum a fully populated object in terms of it's graph, i.e all relationships should be present and traversible.
In code a possible example of new Order creation might be:
[WebService]
public class OrderService
{
[WebMethod]
public void SaveNewOrder(OrderContract orderContract)
{
// Lets assume in this case our Factory has a list of all Customers
// so given an Id it can create the association.
Order order = OrderFactory.CreateNewOrder(orderContract.CustomerId);
// Once again we get the actual order itself, albeit it is new,
// and so Customer and all other objects are already either populated
// by the factory create method and/or are available for lazy loading.
// We can now use the same translator to update all simple attribute fields on
// the new Order instance.
OrderTranslator.OrderContractToOrder(ref order, orderContract);
// We now have the new order instance with all properties populated
// so we can validate and then persist.
if (order.Validate())
{
//Maybe you use a Repository - I use a unit of work but the concept is the same.
orderRepository.Save(order);
}
else
{
//Whatever
}
}
}
So, hope that helps?