Design Pattern Cheatsheet

YAGNI vs Martin’s OCP and Meyer’s OCP

YAGNI is talking about up front software feature. Martin’s OCP is about code ripple effect. Meyer’s OCP is about API backward compatibility.

Framework Design: Dependency Injection, Inversion of Control and AOP

  • For example, in Spring framework, configuration xml need to have bean class to have getter and setter method
  • Example of configuration service class into spring application:
ApplicationContext context = new ClassPathXmlApplicationContext(“springconfig.xml”);
IPersonService personService = (IPersonService) context.getBean(“personService”);
<bean id=”personService” class=”PersonService”>
<property name=”personDao” ref=”personDao” />
</bean>
<bean id=”personDao” class=”PersonDAO” />

The principle of Hollywood of Framework design “We call you, don’t call us.” is inversion of control principle.

Crosscutting concern

AOP concept

  • Joinpoint is somewhere in the classes and methods
  • Pointcut is a collection of one or more Joinpoint
  • Advice is the implementation of Crosscutting concern. Advice type:
  • Before
  • After returning
  • After throwing
  • After
  • Around
  • Aspect is what Crosscutting Concern do I execute (=Advice) at which location in the code (=Pointcut)?
  • Weaving is the way to the place the advice code with the target code at corresponding Pointcuts
@Aspect

@After(“execution(* PersonService.findPerson(…))”)
public void log(JoinPoint joinPoint){
joinPoint.getSignature().getName();
}
<aop:aspectj-autoproxy />
<bean id=”serviceCounter” class=”ServiceCounter” />

Framework Design: White box and Black box

Design Pattern GOF

Behavioral Command

Behavioral Chain of Responsibility

Structural Composite

Behavioral Iterator

Behavioral Mediator

Behavioral Observer

Behavioral State

Behavioral Strategy

Structural Facade

Behavioral Template Method

Structural Proxy & Dynamic Proxy

package proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TimingProxy implements InvocationHandler {

private Object target;
public TimingProxy(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
long start = System.nanoTime();
result = method.invoke(target, args);
long end = System.nanoTime();
long exeTime = end - start;
System.out.println("Execute time for " + target.getClass().getName() + " calling " + method.getName() + " is " + exeTime + "(ns)");
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
package bank.service;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Collection;
import bank.dao.AccountDAO;
import bank.dao.IAccountDAO;
import bank.domain.Account;
import bank.domain.Customer;
import proxy.LogProxy;
import proxy.TimingProxy;
public class AccountService implements IAccountService {
private IAccountDAO accountDAO;
public AccountService(){
// Proxy.newProxyInstance is dynamically create class on the fly and accept 3 arguments:
// loader class
// list of interface to implement
// proxy object and will call invoke method internally
// good video explain about this https://www.youtube.com/watch?v=dEwgHewfvyk

ClassLoader cl = AccountService.class.getClassLoader();
IAccountDAO accountDAO = new AccountDAO();
IAccountDAO logProxyDAO = (IAccountDAO) Proxy.newProxyInstance(cl,new Class[]{IAccountDAO.class},new LogProxy(accountDAO));

IAccountDAO timingAccountDAO = (IAccountDAO) Proxy.newProxyInstance(cl, new Class[]{IAccountDAO.class}, (InvocationHandler) new TimingProxy(logProxyDAO));
this.accountDAO = timingAccountDAO;
}
public Account createAccount(long accountNumber, String customerName) {
Account account = new Account(accountNumber);
Customer customer = new Customer(customerName);
account.setCustomer(customer);
accountDAO.saveAccount(account);
return account;
}
public void deposit(long accountNumber, double amount) {
Account account = accountDAO.loadAccount(accountNumber);
account.deposit(amount);
accountDAO.updateAccount(account);
}
public Account getAccount(long accountNumber) {
Account account = accountDAO.loadAccount(accountNumber);
return account;
}
public Collection&amp;lt;Account&amp;gt; getAllAccounts() {
return accountDAO.getAccounts();
}
public void withdraw(long accountNumber, double amount) {
Account account = accountDAO.loadAccount(accountNumber);
account.withdraw(amount);
accountDAO.updateAccount(account);
}
public void transferFunds(long fromAccountNumber, long toAccountNumber, double amount, String description) {
Account fromAccount = accountDAO.loadAccount(fromAccountNumber);
Account toAccount = accountDAO.loadAccount(toAccountNumber);
fromAccount.transferFunds(toAccount, amount, description);
accountDAO.updateAccount(fromAccount);
accountDAO.updateAccount(toAccount);
}
}
package bank;import java.lang.reflect.Proxy;
import java.util.Collection;
import bank.domain.Account;
import bank.domain.AccountEntry;
import bank.domain.Customer;
import bank.service.AccountService;
import bank.service.IAccountService;
import proxy.TimingProxy;
public class Application {
public static void main(String[] args) {

ClassLoader cl = Application.class.getClassLoader();
IAccountService as = new AccountService();
IAccountService timingAccountService = (IAccountService) Proxy.newProxyInstance(cl, new Class[]{IAccountService.class}, new TimingProxy(as));
IAccountService accountService = timingAccountService;
// create 2 accounts;
accountService.createAccount(1263862, “Frank Brown”);
accountService.createAccount(4253892, “John Doe”);
//use account 1;
accountService.deposit(1263862, 240);
accountService.deposit(1263862, 529);
accountService.withdraw(1263862, 230);
//use account 2;
accountService.deposit(4253892, 12450);
accountService.transferFunds(4253892, 1263862, 100, “payment of invoice 10232”);
// show balances

Collection&amp;lt;Account&amp;gt; accountlist = accountService.getAllAccounts();
Customer customer = null;
for (Account account : accountlist) {
customer = account.getCustomer();
System.out.println(“Statement for Account: “ + account.getAccountnumber());
System.out.println(“Account Holder: “ + customer.getName());
System.out.println(“-Date — — — — — — — — — — — — -”
+ “-Description — — — — — — — — — “
+ “-Amount — — — — — — -”);
for (AccountEntry entry : account.getEntryList()) {
System.out.printf(“%30s%30s%20.2f\n”, entry.getDate()
.toString(), entry.getDescription(), entry.getAmount());
}
System.out.println(“ — — — — — — — — — — — — — — — — — — — — “
+ “ — — — — — — — — — — — — — — — — — — — — “);
System.out.printf(“%30s%30s%20.2f\n\n”, “”, “Current Balance:”,
account.getBalance());
}
}
}

Structural Bridge

Creational Factory Method

Miscellaneous

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store