In the previous blog post, we discussed why design is needed. We saw that using abstractions (functions, classes, modules etc) is a way to allow the code to change safely. We briefly touched on the idea that introducing abstractions has a down side: it can create software that’s difficult to understand. Therefore, the challenge is to find the abstractions that best fit the problem.
How do we know which abstractions are fit and which aren’t? To answer this question, we’ll go on a quest to understand design better.
In how many ways can you print “Hello world!”?
Here are a few “Hello world!” programs:
Version 1: Classic
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
class HelloWorldApp {
public static void main(String[] args) {
print("Hello World!");
}
public static void print(String message){
System.out.println(message);
}
}
Version 4: Object oriented style
class HelloWorldApp {
public static void main(String[] args) {
new HelloWorldPrinter(System.out).print();
}
}
class HelloWorldPrinter{
public HelloWorldPrinter(PrintStream stream){
this.stream = stream;
}
public void print(){
stream.println("Hello world!");
}
}
Version 5: Functional-like style
class HelloWorldApp {
public static void main(String[] args) {
LetterPrinter hPrinter = new LetterPrinter("H");
LetterPrinter ePrinter = new LetterPrinter("e");
LetterPrinter lPrinter = new LetterPrinter("l");
LetterPrinter oPrinter = new LetterPrinter("o");
LetterPrinter spacePrinter = new LetterPrinter(" ");
LetterPrinter wPrinter = new LetterPrinter("W");
LetterPrinter rPrinter = new LetterPrinter("r");
LetterPrinter dPrinter = new LetterPrinter("d");
LetterPrinter exclamationPrinter = new LetterPrinter("!");
LetterPrinter newLinePrinter = new LetterPrinter(System.lineSeparator());
LetterPrinter[] helloWorldPrinters = {
hPrinter, ePrinter, lPrinter, lPrinter, oPrinter,
spacePrinter, wPrinter, oPrinter, rPrinter, lPrinter, dPrinter,
exclamationPrinter, newLinePrinter};
helloWorldPrinters.stream().forEach(printer -> printer.print());
}
}
class LetterPrinter{
String letter;
public LetterPrinter(String letter){
this.letter = letter;
}
public print(){
System.out.print(letter);
}
}
It took me 10 minutes to generate the “Hello world!” programs above. I’m sure if you try you can come up with many more. If a simple program can be written in so many ways, it’s obvious that complex programs can be written in virtually infinite ways. So the question is: which solution is good and which isn’t?
A Counter-Intuitive Conclusion About Design
I’m sure that while reading these examples, you’ve also judged them. You looked at some of them and thought “why do that?”. Based on what criteria did you make the judgment? I’m guessing you’ve applied a set of design principles that you have learned or discovered during your career.
The conclusion is simple, albeit counter-intuitive:
Any design is a set of constraints we as programmers choose to follow when writing code
Programmers don’t have to use classes, but choose to. We don’t have to use lambdas, we choose to do so. We don’t have to use more than one file to write a program, we choose to do so. Our choices define the design.
Design Principles
Design principles are nothing more than sets of constraints that we choose to follow. These constraints have been shown in time to work well together with a certain purpose. Since we’re focused on changeability we’ll only touch design principles that optimize for change.
I know and apply today three different sets of principles:
and what I consider to be the core of all principles: favor low coupling and high cohesion. I combine them with elements I’ve learned about Design by Contract or Domain Driven Design. I add testability to the mix because I can change the software faster whenever I can verify it faster.
We’ll explore these sets of principles in the next articles.
Until then, did you know that we’ll discuss a lot about design at I T.A.K.E. Unconference? Register now to benefit from the collective experience of European software developers.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
var astra = {"break_point":"921","isRtl":"","is_scroll_to_id":"1","is_scroll_to_top":"1","is_header_footer_builder_active":"1","responsive_cart_click":"flyout","is_dark_palette":"","revealEffectEnable":"","ajax_url":"https://mozaicworks.com/wp-admin/admin-ajax.php","infinite_count":"2","infinite_total":"0","pagination":"infinite","infinite_scroll_event":"scroll","no_more_post_message":"No more posts to show.","grid_layout":{"desktop":"3","tablet":1,"mobile":1},"site_url":"https://mozaicworks.com","blogArchiveTitleLayout":"","blogArchiveTitleOn":"","show_comments":"Show Comments","enableHistoryPushState":"1","masonryEnabled":"","blogMasonryBreakPoint":"0","shop_infinite_count":"2","shop_infinite_total":"0","shop_total_products":"1","shop_pagination":"number","shop_infinite_scroll_event":"scroll","shop_no_more_post_message":"No more products to show.","shop_result_count_format":"Showing 1\u2013{count} of {total} results","checkout_prev_text":"Back to my details","checkout_next_text":"Proceed to payment","shop_quick_view_enable":"disabled","shop_quick_view_stick_cart":"","shop_quick_view_auto_height":"1","woo_cart_empty_featured_product":"","single_product_qty_ajax_nonce":"e6a3e76170","quick_view_nonce":"1e9bcee204","single_product_ajax_add_to_cart":"1","is_cart":"","is_single_product":"","view_cart":"View cart","cart_url":"https://mozaicworks.com/cart","checkout_url":"https://mozaicworks.com/checkout","add_to_cart_options_single":"rt_add_to_cart","is_astra_pro":"1","shopRevealEffectEnable":""};
//# sourceURL=astra-theme-js-js-extra
document.addEventListener( 'wpcf7submit', e => turnstile.reset() );
//# sourceURL=cloudflare-turnstile-js-after
var astraAddon = {"is_elementor_active":"","sticky_active":"1","svgIconClose":"\u003Cspan class=\"ast-icon icon-close\"\u003E\u003C/span\u003E","hf_account_show_menu_on":"hover","hf_account_action_type":"link","hf_account_logout_action":"link","header_main_stick":"1","header_above_stick":"","header_below_stick":"","stick_header_meta":"","header_main_stick_meta":"","header_above_stick_meta":"","header_below_stick_meta":"","sticky_header_on_devices":"both","sticky_header_style":"none","sticky_hide_on_scroll":"1","break_point":"921","tablet_break_point":"768","mobile_break_point":"544","header_main_shrink":"1","header_animation_effect":"none","header_logo_width":"","responsive_header_logo_width":{"desktop":200,"tablet":"","mobile":150},"stick_origin_position":"","site_layout":"ast-full-width-layout","site_content_width":"1070","site_layout_padded_width":"1200","site_layout_box_width":"1024","header_builder_active":"1","component_limit":"10","single_product_sticky_product_image":"","single_product_sticky_product_image_top_offset":"0","cart_sticky_cart_totals":"","order_review_toggle_texts":{"toggle_show_text":"Show Order Summary","toggle_hide_text":"Hide Order Summary"},"check_user_exist_nonce":"12993aa20f","woocommerce_login_nonce":"92b78a0084","is_logged_in":"","user_validation_msgs":{"error_msg":"Entered user detail is not a valid.","success_msg":"This user is already registered. Please enter the password to continue."},"checkout_order_review_sticky":"","cartflows_version":"","is_registration_required":"1","is_complete_package":"1","is_header_builder_active":"1"};
//# sourceURL=astra-addon-js-js-extra
var xoo_wsc_params = {"adminurl":"https://mozaicworks.com/wp-admin/admin-ajax.php","wc_ajax_url":"/?wc-ajax=%%endpoint%%","qtyUpdateDelay":"500","notificationTime":"5000","html":{"successNotice":"\u003Cul class=\"xoo-wsc-notices\"\u003E\u003Cli class=\"xoo-wsc-notice-success\"\u003E\u003Cspan class=\"xoo-wsc-icon-check_circle\"\u003E\u003C/span\u003E%s%\u003C/li\u003E\u003C/ul\u003E","errorNotice":"\u003Cul class=\"xoo-wsc-notices\"\u003E\u003Cli class=\"xoo-wsc-notice-error\"\u003E\u003Cspan class=\"xoo-wsc-icon-cross\"\u003E\u003C/span\u003E%s%\u003C/li\u003E\u003C/ul\u003E"},"strings":{"maxQtyError":"Only %s% in stock","stepQtyError":"Quantity can only be purchased in multiple of %s%","calculateCheckout":"Please use checkout form to calculate shipping","couponEmpty":"Please enter promo code"},"nonces":{"update_shipping_method_nonce":"8d5fc997f0"},"isCheckout":"","isCart":"","sliderAutoClose":"1","shippingEnabled":"","couponsEnabled":"1","autoOpenCart":"yes","addedToCart":"","ajaxAddToCart":"yes","showBasket":"always_show","flyToCart":"yes","flyToCartTime":"1500","productFlyClass":"","refreshCart":"no","fetchDelay":"200"};
//# sourceURL=xoo-wsc-main-js-js-extra
var complianz = {"prefix":"cmplz_","debug":"","user_banner_id":"1","set_cookies":[],"block_ajax_content":"0","banner_version":"22","version":"7.5.4","store_consent":"","do_not_track_enabled":"1","consenttype":"optin","region":"eu","geoip":"","dismiss_timeout":"","disable_cookiebanner":"","soft_cookiewall":"","dismiss_on_scroll":"","cookie_expiry":"365","url":"https://mozaicworks.com/wp-json/complianz/v1/","locale":"lang=en&locale=en_US","set_cookies_on_root":"0","cookie_domain":"","current_policy_id":"26","cookie_path":"/","categories":{"statistics":"statistics","marketing":"marketing"},"tcf_active":"","placeholdertext":"Click to accept {category} cookies and enable this content","css_file":"https://mozaicworks.com/wp-content/uploads/complianz/css/banner-{banner_id}-{type}.css?v=22","page_links":{"eu":{"cookie-statement":{"title":"Cookie Policy ","url":"https://mozaicworks.com/cookie-policy-eu"},"privacy-statement":{"title":"Terms And Conditions","url":"https://mozaicworks.com/terms-and-conditions"},"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"us":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"uk":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"ca":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"au":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"za":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}},"br":{"impressum":{"title":"Private: Contact Old","url":"https://mozaicworks.com/?page_id=12523"}}},"tm_categories":"","forceEnableStats":"","preview":"","clean_cookies":"","aria_label":"Click to accept {category} cookies and enable this content","iapi_nav":"fallback"};
//# sourceURL=cmplz-cookiebanner-js-extra
Comments are closed.