DRY Principle
Don't Repeat Yourself Principle
DRY stand for "Don't Repeat Yourself," a basic principle of software development aimed at reducing the repetition of information. The DRY principle is stated as, "Every piece of knowledge or logic must have a single, unambiguous representation within a system."
Structured programming, Aspect Oriented Programming, Component Oriented Programming, and Design Patterns are all, in part, strategies for eliminating duplication.
Duplication manifests itself in many forms:
- Lines of code that look exactly the same.
- Lines of code that are similar to.
- Duplication of implementation.
class UserService {
public void createUser(String email, String password) {
if (isEmailValid(email)) {
// create user
}
}
private boolean isEmailValid(String email) {
String pattern = "email pattern";
Pattern pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
}
class SubscriptionService {
public void subscribe(String topic, String email) {
if (isEmailValid(email)) {
// subscribe
}
}
// By copying and pasting an existing class,
// we have introduced some duplicated code in the codebase.
private boolean isEmailValid(String email) {
String pattern = "email pattern";
Pattern pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
}
class EmailValidator {
public boolean isValid(String email) {
String pattern = "email pattern";
Pattern pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
}
class UserService {
public void createUser(String email, String password) {
if (EmailValidator.isValid(email)) {
// create user ...
}
}
}
class SubscriptionService {
public void subscribe(String topic, String email) {
if (EmailValidator.isValid(email)) {
// subscribe ...
}
}
}
The Template Method Pattern is a common technique for removing higher-level duplication.
interface PageRenderer {
void renderPage();
}
class HomePage implements PageRenderer{
private void showHeader() {
System.out.println("<header />");
}
private void showNavigation() {
System.out.println("<nav />");
}
private void showFooter() {
System.out.println("<footer />");
}
private void showBody() {
System.out.println("Content of home page");
}
@Override
public final void renderPage() {
showHeader();
showNavigation();
showBody();
showFooter();
}
}
class DetailPage implements PageRenderer{
private void showHeader() {
System.out.println("<header />");
}
private void showNavigation() {
System.out.println("<nav />");
}
private void showFooter() {
System.out.println("<footer />");
}
private void showBody() {
System.out.println("Content of detail page");
}
@Override
public void renderPage() {
showHeader();
showNavigation();
showBody();
showFooter();
}
}
interface PageRenderer {
void renderPage();
}
abstract class PageTemplate implements PageRenderer {
private void showHeader() {
System.out.println("<header />");
}
private void showNavigation() {
System.out.println("<nav />");
}
private void showFooter() {
System.out.println("<footer />");
}
protected abstract void showBody();
@Override
public final void renderPage() {
showHeader();
showNavigation();
showBody();
showFooter();
}
}
class HomePage extends PageTemplate {
@Override
protected void showBody() {
System.out.println("Content of home page page");
}
}
class DetailPage extends PageTemplate {
@Override
protected void showBody() {
System.out.println("Content of home detail page");
}
}
public class ProductRepository {
public boolean insert(Product product) {
Session session = null;
try {
session = getConnection();
session.getTransaction().begin();
session.save(product);
session.getTransaction().commit();
return true;
} catch (HibernateException ex) {
log.error("Failed to save product", ex);
return false;
} finally {
closeConnection(session);
}
}
}
public class OrderRepository {
public boolean insert(Order order) {
Session session = null;
try {
session = getConnection();
session.getTransaction().begin();
session.save(order);
session.getTransaction().commit();
return true;
} catch (HibernateException ex) {
log.error("Failed to save order", ex);
return false;
} finally {
closeConnection(session);
}
}
}
Solutions: using Generic class or AOP.
// Using generic class
public class CrudRepository<T> {
public boolean insert(T entity) {
Session session = null;
try {
session = getConnection();
session.getTransaction().begin();
session.save(entity);
session.getTransaction().commit();
return true;
} catch (HibernateException ex) {
log.error("Failed to save " + entity.getClass().getCanonicalName(), ex);
return false;
} finally {
closeConnection(session);
}
}
}
// Using AOP Framework like AspectJ or Spring AOP
@Transactional
public class CrudRepository<T> {
private EntityManager em;
public boolean insert(T entity) {
em.save(entity);
}
}
Last modified 3mo ago