{"id":2006,"date":"2023-12-28T00:33:07","date_gmt":"2023-12-28T00:33:07","guid":{"rendered":"http:\/\/write.muthu.co\/?p=2006"},"modified":"2024-02-17T02:13:52","modified_gmt":"2024-02-17T02:13:52","slug":"dry-dont-repeat-yourself","status":"publish","type":"post","link":"http:\/\/write.muthu.co\/dry-dont-repeat-yourself\/","title":{"rendered":"DRY (Don’t Repeat Yourself)"},"content":{"rendered":"\n
The DRY principle, which stands for Don’t Repeat Yourself<\/em><\/strong>, is a principle in software engineering that emphasizes avoiding code duplication. It basically states that every piece of knowledge within a system should have a single, unambiguous, authoritative representation.<\/p>\n\n\n\n Imagine you’re writing a recipe for chocolate chip cookies. If you need to measure 1 cup of flour in three different parts of the recipe, you wouldn’t write “1 cup of flour” three times. Instead, you’d declare it once at the beginning and then simply refer to it when needed. This saves you time and effort, and it also makes the recipe easier to read and maintain.<\/p>\n\n\n\n The same logic applies to software code. Repeating code not only wastes time and makes the code harder to understand, but it also increases the risk of errors. If you change something in one place, you have to remember to change it everywhere else it’s repeated.<\/p>\n\n\n\n There are many ways to implement the DRY principle in your code. Here are a few examples:<\/p>\n\n\n\n If you find yourself writing the same block of code in multiple places, put it in a function and call it wherever you need it. Take for example a simple You can see that Here a bit more complicated example, try and refactor the below method using DRY principle.<\/p>\n\n\n\n Here’s the refactored code using DRY principle<\/strong><\/p>\n\n\n\n Explanation of Changes:<\/strong><\/p>\n\n\n\n – Extracted Common Logic:<\/strong> The formatting logic for – Ternary Operators for Conciseness:<\/strong> Ternary operators are used to conditionally assign values to – Single String.format() Call:<\/strong> The final string formatting is now done in a single Classes can group related functions and data together, which can help to reduce code duplication. Here\u2019s an example illustrating how we can achieve this and adhere to the DRY principle:<\/p>\n\n\n\n Imagine you\u2019re building a program to manage a library\u2019s book collection. You need to perform various operations on books, such as:<\/p>\n\n\n\n Non-DRY Approach:<\/strong><\/p>\n\n\n\n Without classes, you might create separate functions for each operation, leading to code duplication:<\/p>\n\n\n\n DRY Approach with Classes:<\/strong><\/p>\n\n\n\n By creating a Now, you can create book objects and perform operations directly on them:<\/p>\n\n\n\n If you have a value that is used in multiple places, make it a constant. This will make your code more readable and prevent typos.<\/p>\n\n\n\n Here\u2019s an example demonstrating how using constants for repeated values can improve code readability, maintainability, and prevent typos, adhering to the DRY principle:<\/p>\n\n\n\n Without Constants:<\/strong><\/p>\n\n\n\n With Constants:<\/strong><\/p>\n\n\n\n Abstractions can help you to hide the implementation details of your code, which can make it easier to reuse and maintain.<\/p>\n\n\n\n Here\u2019s an example demonstrating how abstractions can help hide implementation details, making code more reusable and maintainable, adhering to the DRY principle. Imagine you\u2019re building a program that interacts with different types of databases (MySQL, PostgreSQL, etc.). You want to write code that can work with any database without needing to change the core logic for each type.<\/p>\n\n\n\n Without Abstraction:<\/strong><\/p>\n\n\n\n Without abstraction, you might have separate functions for each database type, leading to code duplication and tight coupling:<\/p>\n\n\n\n Then, create concrete implementations of this interface for each database type:<\/p>\n\n\n\n Now, your main code can work with any database through the common interface, without knowing the underlying implementation:<\/p>\n\n\n\n Following the DRY principle is a great way to write cleaner, more maintainable, and less error-prone code. It may take some effort to get used to it at first, but the benefits are well worth it in the long run.<\/p>\n","protected":false},"excerpt":{"rendered":" The DRY principle, which stands for Don’t Repeat Yourself, is a principle in software engineering that emphasizes avoiding code duplication. It basically states that every piece of knowledge within a system should have a single, unambiguous, authoritative representation. Imagine you’re writing a recipe for chocolate chip cookies. If you need to measure 1 cup of […]<\/p>\n","protected":false},"author":1,"featured_media":2040,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69],"tags":[],"_links":{"self":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/2006"}],"collection":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/comments?post=2006"}],"version-history":[{"count":5,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/2006\/revisions"}],"predecessor-version":[{"id":2044,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/posts\/2006\/revisions\/2044"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/media\/2040"}],"wp:attachment":[{"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/media?parent=2006"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/categories?post=2006"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/write.muthu.co\/wp-json\/wp\/v2\/tags?post=2006"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}Use functions<\/strong><\/h2>\n\n\n\n
MathOperations<\/code> class as shown below.<\/p>\n\n\n\n
public class MathOperations {\n \n public int sum(int a, int b) {\n return a + b;\n }\n\n public double average(int a, int b) {\n return (a + b) \/ 2;\n }\n}<\/code><\/pre>\n\n\n\n
a+b<\/code> has been repeated in both the methods, we can remove this repetition by modiyfing our code as shown below:<\/p>\n\n\n\n
public class MathOperations {\n\n public int sum(int a, int b) {\n return a + b;\n }\n\n public double average(int a, int b) {\n return sum(a, b) \/ 2; \/\/ reused\n }\n}<\/code><\/pre>\n\n\n\n
public static void printGuessStatistics(char candidate, int count) {\n String number;\n String verb;\n String pluralModifier;\n\n if (count == 0) {\n number = \"no\";\n verb = \"are\";\n pluralModifier = \"s\";\n } else if (count == 1) {\n number = \"1\";\n verb = \"is\";\n pluralModifier = \"\";\n } else {\n number = Integer.toString(count);\n verb = \"are\";\n pluralModifier = \"s\";\n }\n\n System.out.println(String.format(\"There %s %s %s%s\", verb, number, candidate, pluralModifier));\n}<\/code><\/pre>\n\n\n\n
public static void printGuessStatistics(char candidate, int count) {\n String number = formatCount(count);\n String verb = count == 1 ? \"is\" : \"are\";\n String pluralModifier = count != 1 ? \"s\" : \"\";\n\n System.out.println(String.format(\"There %s %s %s%s\", verb, number, candidate, pluralModifier));\n}\n\nprivate static String formatCount(int count) {\n if (count == 0) {\n return \"no\";\n } else if (count == 1) {\n return \"1\";\n } else {\n return Integer.toString(count);\n }\n}<\/code><\/pre>\n\n\n\n
number<\/code>,
verb<\/code>, and
pluralModifier<\/code> has been extracted into a separate private function
formatCount()<\/code>.<\/p>\n\n\n\n
verb<\/code> and
pluralModifier<\/code> based on
count<\/code>, making the code more concise.<\/p>\n\n\n\n
String.format()<\/code> call, using the variables directly.<\/p>\n\n\n\n
Use classes<\/h2>\n\n\n\n
\n
String createBookString(String title, String author, String ISBN) {\n \/\/ Create a string representation of a book\n}\n\nvoid displayBook(String title, String author, String ISBN) {\n \/\/ Print book information\n}\n\nboolean isBookAvailable(String title, String author, String ISBN) {\n \/\/ Check if book is available\n}<\/code><\/pre>\n\n\n\n
Book<\/code> class, you can encapsulate book-related data and actions together:<\/p>\n\n\n\n
class Book {\n private String title;\n private String author;\n private String ISBN;\n private boolean isAvailable = true;\n\n public Book(String title, String author, String ISBN) {\n this.title = title;\n this.author = author;\n this.ISBN = ISBN;\n }\n\n public String getTitle() {\n return title;\n }\n\n public void setTitle(String title) {\n this.title = title;\n }\n\n \/\/ ... other getters and setters for author, ISBN, etc.\n\n public void displayBookInfo() {\n System.out.println(\"Title: \" + title);\n System.out.println(\"Author: \" + author);\n System.out.println(\"ISBN: \" + ISBN);\n \/\/ ... other book information\n }\n\n public boolean isAvailable() {\n return isAvailable;\n }\n\n public void setAvailable(boolean available) {\n isAvailable = available;\n }\n}<\/code><\/pre>\n\n\n\n
Book book1 = new Book(\"The Lord of the Rings\", \"J.R.R. Tolkien\", \"1234567890\");\n\/\/ Output: Title: The Lord of the Rings, Author: J.R.R. Tolkien, ISBN: 1234567890\nbook1.displayBookInfo(); \n\/\/ Mark book as unavailable\nbook1.setAvailable(false); <\/code><\/pre>\n\n\n\n
Use constants<\/h2>\n\n\n\n
public class InvoiceCalculator {\n public double calculateTotal(double subtotal) {\n double taxRate = 0.07; \/\/ Sales tax rate\n double shippingFee = 5.99; \/\/ Fixed shipping fee\n\n double taxAmount = subtotal * taxRate;\n double total = subtotal + taxAmount + shippingFee;\n\n return total;\n }\n\n public void printInvoice(double total) {\n System.out.println(\"Subtotal: $\" + total);\n System.out.println(\"Tax (7%): $\" + (total * 0.07)); \/\/ Typo: tax rate hardcoded again\n System.out.println(\"Shipping: $5.99\");\n System.out.println(\"Total: $\" + total);\n }\n}<\/code><\/pre>\n\n\n\n
public class InvoiceCalculator {\n public static final double TAX_RATE = 0.07; \/\/ Declare constants\n public static final double SHIPPING_FEE = 5.99;\n\n public double calculateTotal(double subtotal) {\n double taxAmount = subtotal * TAX_RATE;\n double total = subtotal + taxAmount + SHIPPING_FEE;\n\n return total;\n }\n\n public void printInvoice(double total) {\n System.out.println(\"Subtotal: $\" + total);\n System.out.println(\"Tax (7%): $\" + (total * TAX_RATE)); \/\/ Use the constant\n System.out.println(\"Shipping: $\" + SHIPPING_FEE);\n System.out.println(\"Total: $\" + total);\n }\n}<\/code><\/pre>\n\n\n\n
Use abstractions<\/h2>\n\n\n\n
public interface Database {\n void connect();\n void executeQuery(String query);\n void disconnect();\n}<\/code><\/pre>\n\n\n\n
public class MySQLDatabase implements Database {\n \/\/ Implementation for MySQL-specific connection, query execution, etc.\n}\n\npublic class PostgreSQLDatabase implements Database {\n \/\/ Implementation for PostgreSQL-specific connection, query execution, etc.\n}<\/code><\/pre>\n\n\n\n
public void saveData(Data data, Database database) {\n database.connect();\n database.executeQuery(\"INSERT INTO ...\"); \/\/ Use a generic query\n database.disconnect();\n}<\/code><\/pre>\n\n\n\n