Sunday, May 17, 2020

Designing with patterns

Software is a craft and designing is the heart of it.

While there can be supporters of different ways of designing a system like "create the design first" or "letting the design evolve" and pros and cons of either  ways.. but, considering the agile way of software making (and evolving requirements), it is essential to inculcate the value of "evolving design" in software making.

Even if we have a design, it is bound to evolve if it needs to address the new requirements or when we unearth something which the design can't address while implementing the requirements.. In this aspect, refactoring is extremely important and TDD is a definite way to enable "fast refactoring" by creating faster feedback cycles.

While software design is all about keeping things clean, it is also about ability to make changes to the software so that it can address the unseen future requirements easily.

It is critical to know/foresee the problems of the software and minimise them .. While the ways of designing can be differ, there is something which is common in both manners of designing.. that is applying the design patterns... There can be a middle ground struck in the ways where an initial minimal design is created to understand the problem domain and devise the possible solutions and then, implementing the solution by TDD where you let the design freely evolve and also, embellish the thought out design with actual problem solutions encountered in the process.

Irrespective of the designing methodology, it is important to know the common problems software presents and the solutions to these common problems.. Welcome to "Design Patterns" !!

It is important to know the context and the pattern(s) applicable for the problems that might surface in the software. Below is a brief summary of the patterns from the GoF pattern catalog:

Creational

Singleton
: If we need only one instance of a class - either due to cost of the resource creation or nature of the business entity. E.g. ConnectionFactory, HibernateConfiguration, java.lang.RunTime.

Factory: Avoid tight coupling the client and specific object/handler, implement single responsibility principle for creating classes,  . E.g. Creating Chess Pieces, Calendar.getInstance(), ResourceBundle.getBundle().

Abstract Factory: Creation of different objects, usually of same type but multiple families. E.g. Theme UI Controls(Buttons, Text box, Checkbox, etc), javax.xml.parsers.DocumentBuilderFactory#newInstance().

Builder: Allows you to produce different types and representations of an object using the same construction code. Lets you construct complex objects step by step. This is applicable to get rid of the telescopic constructors for a class. e.g. StringBuilder.append(), StringBuffer.append(), or below code snippet:

AmazonS3 s3client = AmazonS3ClientBuilder
  .standard()
  .withCredentials(new AWSStaticCredentialsProvider(credentials))
  .withRegion(Regions.US_EAST_2)
  .build();

Prototype: If an object creation is costly/time-consuming, the new objects can be created using existing objects. It can be implemented using Prototype and Prototype registry. Example of this is "java.lang.Object#clone()" (the class has to implement java.lang.Cloneable)

Structural

Adapter: To avoid tight coupling with third party libraries or code which cannot be modified or is not part of the code base, Adapter pattern is recommended. Example: Wrapping a third party logging library in an application class, java.util.Arrays#asList().

Composite: An abstraction which represents "Is-A" as well as a "Has-A" relationship. This represents a part-whole hierarchy. E.g. Query Conditions, which can be nested.

Decorator: A class which wraps a type of itself. This is usually doing additional processing on top of the processing done by the complete chain of wrapped classes. E.g. java.io.InputStream, java.io.OutputStream, real life examples could be Pizza with toppings and cheese, different types of sandwitches, Ice-creams etc.

Bridge: Decouple an abstraction from its implementation so that two can vary independently. Example of this could be Message/MessageSender(abstraction/implementor) or Vehicle/VehicleManufacturer(abstraction/implementor). Message can be of type TextMessage/EmailMessage and similar hierarchy for TextMessageSender/EmailMessageSender or Vehicle can be Car/Bike and similar hierarchy for CarWorkshop/BikeWorkshop.

Flyweight: It is a shared object that can be used at multiple places with a distinction of intrinsic and extrinsic state. Example of this Integer.valueOf (similarly Boolean, Byte, Long, etc) and chess pieces of rook, knight, bishop, pawns.

To be explored more: Facade, Proxy.

Behavioural

Strategy:
 Encapsulate a family of algorithms and let the clients use them interchangeably. e.g. java.util.Comparator#compare(), executed by among others Collections#sort(), movement rules of different chess pieces.

Template Method: Create a skeleton/template of an algorithm and defer the details/logic of some step(s) to subclasses. Example : Struts used this for Action.

Visitor: Represents operation(s) for elements of object structure (E.g. a class hierarchy) which is typically not the responsibility of the object structure. This allows addition of new operation without change in the object structure. This is also called as a 'double dispatch' pattern since it displays polymorphism twice - once as a type of visitor and once as a particular class in the structure.

State: This lets an object change its behaviour based on its intrinsic state. e.g. javax.faces.lifecycle.LifeCycle#execute() (controlled by FacesServlet, the behaviour is dependent on current phase (state) of JSF lifecycle).

Observer: This is a publisher-subscriber pattern and is typical to represent one-to-many relation between an object and dependents for any state change in the object. E.g. javax.servlet.http.HttpSessionBindingListener, javax.servlet.http.HttpSessionAttributeListener

Chain Of Responsibility: This pattern decouples the sender from the receiver/handlers of a request and typically, has source of request and a series of receivers/handlers. E.g. javax.servlet.Filter#doFilter(), AuthenticationChain, Permission/Visibility Chain, etc.

Command: This pattern encapsulates a request as an object, decouples a sender and a receiver, allows to parameterise clients/methods with different requests. This is typically useful for queueing, scheduling or logging of requests and supports undo operations very well. This is also particularly useful if same command is used at many places like Copying with button, context menu and a shortcut key. Example of this is implementations of java.lang.Runnable.

To be explored more: Interpreter, Memento, Mediator, Iterator.

Sunday, November 17, 2019

React (and a bit of EcmaScript)

Following is a gist of a course on Modern javascript and React..


ES2015 (ES6):


var, let, const (blocks and function blocks)


Arrow function (difference of ‘this’ in normal function(calling environment) and arrow function(defining environment)


Object Literals (shortcut function definition, dynamic property definition, block property usage)


Destructuring (arrays and objects)


Rest and Spread (array splitting and copying)


Template Strings (use back tick [`] instead of ‘ and “ - use dynamic evaluation/interpolation)


Classes


Promise and async/await


REACT


What is React?


React is a library to build User interfaces.. Easy way to start learning React is below:
  1. React’s design concepts
  2. JSX and event handlers, data, and APIs
  3. React hooks
  4. Communicating between components
  5. Creating local environment

Why React?

  1. The virtual browser (vs DOM API)
  2. “Just javascript”
  3. Reach Native (for the win)
  4. Battle-tested (@ Facebook)
  5. Declarative Language

React overview:

  1. Components
    • Like Functions
    • Inputs: props, state| Output: UI
    • Reusable and composable
  2. React updates
    • React will react
    • Take updates to the browser
  3. Virtual views in memory
    • Generate HTML using Javascript
    • No HTML template language
    • Tree reconciliation

React Components

  1. Function Component
  2. Class Component

Inputs to the component are props and state. The output is JSX (looks like HTML but is javascript syntax). Props are list of attributes and are immutable for a component. Components can change the state and React uses it to auto-reflect the changes in the browser.

Data and Behavior can flow from parent to child component, via props.


Components are reusable.


The state management should be in the closest parent to the components using the state.

React Hooks

React Hooks are functions that let us hook into the React state and lifecycle features from function components. By this, we mean that hooks allow us to easily manipulate the state of our functional component without needing to convert them into class components. Example of React Hook:
  • useState

Tree Reconciliation

Reach compares the versions of virtual dom to render only those React elements that need to be re-rendered, and not the entire DOM.

Trying out React

You can use jscomplete.com/playground for quick startup which has React and ReactDOM pre-loaded and also understands JSX and ES2015 syntax. ‘React Developer Tools’ is a good extension for the browser.

Tuesday, September 24, 2019

Not just ‘GO’ish in the Golang training, Thankfully !

This article is a postquel to training for ‘Golang’, and below are some excerpts which were not related to ‘Golang’ at all ! Thanks to ‘Christian Hujer’ for sharing this...

  • Use-cases are primary driver for choosing a programming language/technology, but principles and practices are more important than the language or technology in the craft of software development.
  • A mobile device has pretty much become similar to a laptop in terms of processor core(s)/power and memory configuration, but the technologies on them are quite different - shouldn’t these converge? ChromeBooks are based on Chromium OS. Also, Rust and WebAssembly were mentioned in the same context.
  • Functional programming was devised in 1950s in academic circles and early functional-flavored language was Lisp, developed some time around 1958.
  • The billion dollar mistake by Tony Hoare - the “Null Pointer References”; estimating that software engineers have spent at least a billion dollar worth dealing with problems due to null pointer references.
  • Java started with ‘green’ threads in the initial releases because of Java being targeted for Sun’s SPARC machines. Later on, to comply to different processor architectures, Java moved from the ‘green’ threads to ‘native’ threads, since Java 1.3. Additional Information gathered: "Green" is earlier JVM threads project code-name.
  • There were no changes required in JVM to implement the Lambda expressions in Java 1.8, which is implemented using “InvokeDynamic” instruction introduced in Java 7.
  • HTTP/2 is binary(instead of text-based), fully multiplexed and uses header compression and gRPC is based on HTTP/2. Additional information gathered”: Google’s SPDY is the precursor of HTTP/2.
  • Vast majority of the docker images are based on Alpine Linux, which in turn is based on Busybox.
  • There is a JVM running in the chip of a credit card as well.
  • The definition of the pipeline should be in the application source code(like Jenkins 2 declarative pipeline) and the actual automation code should be non-editable outside the application source code. 

Wednesday, August 28, 2019

Microservices Best Practices


  • Instead of a monorepo, structure individual repositories per microservice. This allows for granular access control (like contributors, reviewers, viewers, etc) and also allows for individual microservices build versioning.
  • Serverless deployments like AWS Lambda, Google Cloud Functions can fit well as part of microservices architecture, for small ad-hoc functions.
  • The microservices should employ loosely-coupled messaging communication style. As per the ‘Reactive Systems’ manifesto, the services should be ‘message-driven’, which ensures loose-coupling, isolation and location transparency. Apache Kafka, AWS Kinesis can serve the purpose of asynchronous messaging.
  • Architect group of microservies to be deployed as containers on a single host(cluster). Microservices should be deployed in containers like docker. There are multiple strategies like ‘multiple services per host’, ‘single service per host’. In order to leverage the benefits of containerization (multiple containers per host) and also to address scalability (and cost) concerns, architect the services as a group of services which can be deployed in single host (a.k.a cluster). There will be multiple clusters with each cluster having group of microservices.
  • Evaluate the technology(ies) to be used in each microservice separately. The requirements from the microservice should drive the choice of technologies, e.g. concurrency, serverless deployment, subdomain requirements, etc.
  • Use a microservices chassis framework like Spring Boot/Dropwizard (Java) or Go Kit, Micro, Gizmo (Go) for microservices cross-cutting concerns like logging, health check, distributed tracing, metrics, etc.
  • With advancement in UI frameworks like Angular, React, etc, ‘client-side UI composition’ should be utilized which composes the UI fragments rendered from multiple microservices, rather than ‘server-side page fragment composition’.
  • The observability of microservices is a critical aspect. Ensure implementing distributed tracing, application metrics, log aggregation. Open Zipkin, Dapper, Jaeger can be used for distributed tracing. Micrometer, Prometheus can be used for application metrics. Log aggregation can be done via AWS Cloudwatch, Splunk, etc.
  • Service component tests should be implemented with test doubles for the associated services. Framework like WireMock can be used for this purpose.
  • From the ‘Reliability’ perspective, implement Circuit Breaker pattern for failing requests beyond a threshold for a microservice. Netflix Hystrix can be used for this purpose.
  • Try to avoid API versioning; keep the APIs backward compatible. If API versioning is required, evaluate URL, request parameter, request header strategies for API versioning.
  • Evaluate cloud native architecture as next stage of microservices architecture which gives advantages like using sidecar proxies and service meshes.

Wednesday, July 3, 2019

Spring / Spring-Boot Best Practices


  • Spring Java Configuration is recommended over xml configuration.
    • XML is not type safe, runtime error checking/corrections.
    • Java configuration can be debugged.
  • Avoid injecting Spring in domain classes. OK to inject spring in spring classes.
    • Easy to extract/port domain, if required.
    • Inject beans in spring configuration classes.
    • You can use javax annotations like @Named and @Inject in domain classes.
  • Minimise spring component scan, OK for controllers package.
    • You can inject spring (like @Autowired) here, where Spring exists like @RestController.
    • Slows down the app startup.
  • Exception handling can be a combination of central (preferred as much as it can be done) and local (as required)
    • Spring 3.2 had introduced @ControllerAdvice, in addition to the erstwhile @ExceptionHandler. This enables you implement centralised exception handling.
    • Spring 5.0 has introduced ResponseStatusException, which gives you more control over type of exceptions that can be raised.
    • Recommended approach is to have one exception being handled in one of the above manner.
  • Logging should be considered as a cross cutting concern, in addition to the method specific logging, as required.
    • Practice 1: Suggest to have Trace level logs and Debug level logs for every method. This can be done by @Around advice in a Logger aspect. Trace level log is entry/exit log and Debug level log is input parameters and return parameter for a method.
    • Practice 2: Suggest to have request tracing logs at the entry/exit of the http request. Do not log input param and return params. This can be done by @Around advice in a Logger aspect. This is typical of applications where there is very good unit test and component test coverage.
    • Specific important logging should be done in addition to the Logger Aspect, irrespective of Practice 1 or Practice 2.
    • Implement dynamic log level changes. This is available in spring boot actuator, but will need explicit handling in case of a clustered microservice, in case of Practice 1 of logging.
  • You can use Spring Initialzr for setting up Spring boot project, for the required boot modules.
    • Starter modules for keycloak, flyway, data, etc available.
    • This is typically useful only for initial setup of the project.
  • Use SpringBootTest or SpringJUnit4ClassRunner for Unit tests. Avoid using PowerMock.
  • Maven specific : Have a central spring dependency version management - this is called BOM(Bill Of Materials). The Spring BOM can be inherited as a parent or can be imported in dependency management.
  • Microservices specific - Distributed Tracing: The observability aspect of “Distributed tracing” can be implemented using Spring Sleuth/Zipkin.
  • Application Metrics - You can use Spring Boot Actuator. Micrometer is the Spring Boot 2’ application metrics collector - it is a dimensional-first metrics collection facade. Micrometer is included in Spring Boot 2’s actuator. It also has been back ported in Spring Boot 1.5, 1.4 and 1.3 with the addition of another dependency. Micrometer gives the flexibility of integration with dimensional monitoring systems like Cloudwatch, Prometheus, InfluxDB, New Relic, etc.

Sunday, July 22, 2018

Evolving Technology


Technology is the lifeline of the current day world. The characteristic of today’s technology is that it’s too wide, too deep, too advanced; in simple words, it’s vast.

                Coming closer home, software is no exception to the technology landscape mentioned above. Software, in itself, is a vast field and the evolution of software is unfolding at an unprecedented pace. The laser-sharp human intelligence, the competition to be disruptive and the mad money being poured into the space is not making things any easier.

                Coming even closer home, the application development is no exception to the technology and software landscape. It is expected that engineers know all the vast number of technologies; if not know, then at least be able to learn them at a lightening pace. To add to the woes, the code quality, the design quality, the architecture quality and the functional quality are expected to be nothing less than the best.

                Whether the above scenario is excitement to you or causes stress, pretty much defines what future holds in its arms for you, as an individual. If you can ride the wave of technology evolution, it holds the potential for your evolution, as an individual.

                The humans, as a race on our planet, understand the universe the best and it can only get better. Whether we can sustain the technological advancements and somehow balance it with the environmental concerns will hold the key to our future. Probably, the only question is ‘how long will we survive’?

Thursday, June 21, 2018

Knowing Technology

Entry barrier is always high. Making Knowledge enticing enough, interesting enough and simple enough” – The main roadblock in knowing technology is that it isn’t enticing enough, interesting enough and of course, it’s highly complex. Artificial intelligence as a topic is quite hot and quite attractive, but beyond the definition or probably an overview, isn’t enticing enough and is difficult enough to delve further and deeper. And probably, there is no easy trick to make it enticing enough, interesting enough and simple enough.

Take up a challenge” – Doing a certain action and being successful requires perfect ingredients. You should have enough resources to take up and successfully complete a challenge. Choosing a correct goal is the most fundamental step of taking up a challenge. ‘SMART’ goals stand for Specific, Measurable, Achievable, Relevant and Time bound goals.

Evaluating Options” – Being at the cross road of taking up a challenge, the different options that are cropping up are building a small starter NLP(natural language processing) library, a small starter in-memory java database and a small starter programming language.

Finalizing the option” – In the current context, I think the most enticing option that I can start with is a small starter java in-memory database, which will present me with the challenges of knowing a database technology and learning the java to a deeper level. However, I would like to receive opinions, suggestions, ideas, inputs and anything else that will help me finalize the challenge I enroll to. Please be generous and provide your thoughts to me.

Reaching out further” – Whichever challenge I enroll to, I think I will be reaching out to quite a few of you guys. Hopefully, this will help me know technology better and I believe I will have to count on the knowledge and experience available to keep moving ahead in the endeavor.