This document provides an overview of clean code principles and best practices. Some of the key topics covered include:
- Using meaningful variable, function, and class names.
- Avoiding flag arguments and side effects in functions.
- Preferring exceptions over returning error codes.
- Properly formatting code and comments for readability.
- Following object-oriented principles like high cohesion and single responsibility.
- Adhering to SOLID design patterns and GRASP patterns.
ES3-2020-06 Test Driven Development (TDD)David Rodenas
Basics of TDD. Including why? Why it is discipline. Typical Pitfalls. Kinds of TDD, and a Recipe so anyone can do testing quickly. And lots of examples.
How difficult is to automatically test the HelloWorld.
We fix it and other many difficult scenarios with techniques like:
- lower "s" singleton
- law of demeter
- dependency injection
- and more examples
A summary of clean code concepts and tips along with some examples and good practices.
These are the slides translated in English from my talk on Clean Code to my coworkers back then
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
In this session, we will present real life applications of compiler techniques helping kaChing achieve ultra confidence and power its incredible 5 minutes commit-to-production cycle [1]. We'll talk about idempotency analysis [2], dependency detection, on the fly optimisations, automatic memoization [3], type unification [4] and more! This talk is not suitable for the faint-hearted... If you want to dive deep, learn about advanced JVM topics, devoure bytecode and see first hand applications of theoretical computer science, join us.
[1] http://eng.kaching.com/2010/05/deployment-infrastructure-for.html
[2] http://en.wikipedia.org/wiki/Idempotence
[3] http://en.wikipedia.org/wiki/Memoization
[4] http://eng.kaching.com/2009/10/unifying-type-parameters-in-java.html
Rule 1: Follow a consistent coding standard
Rule 2: Name things properly, long variable and function names are allowed
Rule 3: Be expressive, write code as you speak and be optimally verbose
Rule 4: Max indent per method should be 2, in case of exceptions 3
Rule 5: Avoid creating god object and long methods
Rule 6: Keep the method in one place, inject the class and call it, DRY
Rule 7: Avoid in-line comments (comment with code), put comments in the method doc
Creational Pattern of the design pattern.
Introducing 6 type patterns and also including the pros and cons. It's easy to understand what's kind of scenario it should be used.
A brief overview about how to write human readable and meaningful code. Here is described why and how to write meaningful names of variables or method, what to follow about writing a function for SRP / Open-Closed principle rule, when to write comments and rules of Code Formatting. Advantages of clean code is also described here.
ES3-2020-06 Test Driven Development (TDD)David Rodenas
Basics of TDD. Including why? Why it is discipline. Typical Pitfalls. Kinds of TDD, and a Recipe so anyone can do testing quickly. And lots of examples.
How difficult is to automatically test the HelloWorld.
We fix it and other many difficult scenarios with techniques like:
- lower "s" singleton
- law of demeter
- dependency injection
- and more examples
A summary of clean code concepts and tips along with some examples and good practices.
These are the slides translated in English from my talk on Clean Code to my coworkers back then
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
In this session, we will present real life applications of compiler techniques helping kaChing achieve ultra confidence and power its incredible 5 minutes commit-to-production cycle [1]. We'll talk about idempotency analysis [2], dependency detection, on the fly optimisations, automatic memoization [3], type unification [4] and more! This talk is not suitable for the faint-hearted... If you want to dive deep, learn about advanced JVM topics, devoure bytecode and see first hand applications of theoretical computer science, join us.
[1] http://eng.kaching.com/2010/05/deployment-infrastructure-for.html
[2] http://en.wikipedia.org/wiki/Idempotence
[3] http://en.wikipedia.org/wiki/Memoization
[4] http://eng.kaching.com/2009/10/unifying-type-parameters-in-java.html
Rule 1: Follow a consistent coding standard
Rule 2: Name things properly, long variable and function names are allowed
Rule 3: Be expressive, write code as you speak and be optimally verbose
Rule 4: Max indent per method should be 2, in case of exceptions 3
Rule 5: Avoid creating god object and long methods
Rule 6: Keep the method in one place, inject the class and call it, DRY
Rule 7: Avoid in-line comments (comment with code), put comments in the method doc
Creational Pattern of the design pattern.
Introducing 6 type patterns and also including the pros and cons. It's easy to understand what's kind of scenario it should be used.
A brief overview about how to write human readable and meaningful code. Here is described why and how to write meaningful names of variables or method, what to follow about writing a function for SRP / Open-Closed principle rule, when to write comments and rules of Code Formatting. Advantages of clean code is also described here.
Introduction of Clean Code
~ What is Bad Code and Good Code ~
Presented by Jeremiah Caballero on June 26, 2019.
It's an introduction of "Clean Code" referring to the Robert C.Martin's "Clean Code".
Core Java Programming Language (JSE) : Chapter VI - Class DesignWebStackAcademy
Class design that follows established principles is usually correct, reusable, extensible, and easy to maintain. But, that does not mean they are providence. A situation may arise where normal principles find it inadequate to fit in. In such a case, the purpose or objective should be the basic ingredient of design decision. But, such a situation may arise once in a blue moon. It is always a good idea to begin with a proper design guidelines rather than grope in the dark and become sorry in the later phases of development.
Before designing a class, we must understand that a class is an abstraction of a certain aspect of a problem. The objective is to filter those aspects that are important for the purpose and ignore those that are unimportant. Sometimes, given a problem, one may find it difficult to identify aspects that are the right candidate to be classified. After all, abstraction in computing is a poor representation of reality; even establishing a simple relationship can be quite complex. Still, they do represent because we insist. Depending upon the complexity of the problem, it can even be a challenge for a seasoned programmer. Perhaps, a way out of the situation is to focus on the purpose, because it is the purpose that determines what is to be taken into account and what to suppress. Also, depending upon the purpose to be served, a variety of abstractions of the same thing is possible. For example, a Media class construct may be designed differently depending upon the type of media it targets, such as print media or screen.
Encapsulation is the process of wrapping up data (properties) and behavior (methods) of an object into a single unit, and the unit here is a Class (or interface). English meaning of Encapsulate is to enclose or be enclosed in or as if in a capsule.
Large Language Models and the End of ProgrammingMatt Welsh
Talk by Matt Welsh at Craft Conference 2024 on the impact that Large Language Models will have on the future of software development. In this talk, I discuss the ways in which LLMs will impact the software industry, from replacing human software developers with AI, to replacing conventional software with models that perform reasoning, computation, and problem-solving.
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...informapgpstrackings
Keep tabs on your field staff effortlessly with Informap Technology Centre LLC. Real-time tracking, task assignment, and smart features for efficient management. Request a live demo today!
For more details, visit us : https://informapuae.com/field-staff-tracking/
GraphSummit Paris - The art of the possible with Graph TechnologyNeo4j
Sudhir Hasbe, Chief Product Officer, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Globus
Large Language Models (LLMs) are currently the center of attention in the tech world, particularly for their potential to advance research. In this presentation, we'll explore a straightforward and effective method for quickly initiating inference runs on supercomputers using the vLLM tool with Globus Compute, specifically on the Polaris system at ALCF. We'll begin by briefly discussing the popularity and applications of LLMs in various fields. Following this, we will introduce the vLLM tool, and explain how it integrates with Globus Compute to efficiently manage LLM operations on Polaris. Attendees will learn the practical aspects of setting up and remotely triggering LLMs from local machines, focusing on ease of use and efficiency. This talk is ideal for researchers and practitioners looking to leverage the power of LLMs in their work, offering a clear guide to harnessing supercomputing resources for quick and effective LLM inference.
In software engineering, the right architecture is essential for robust, scalable platforms. Wix has undergone a pivotal shift from event sourcing to a CRUD-based model for its microservices. This talk will chart the course of this pivotal journey.
Event sourcing, which records state changes as immutable events, provided robust auditing and "time travel" debugging for Wix Stores' microservices. Despite its benefits, the complexity it introduced in state management slowed development. Wix responded by adopting a simpler, unified CRUD model. This talk will explore the challenges of event sourcing and the advantages of Wix's new "CRUD on steroids" approach, which streamlines API integration and domain event management while preserving data integrity and system resilience.
Participants will gain valuable insights into Wix's strategies for ensuring atomicity in database updates and event production, as well as caching, materialization, and performance optimization techniques within a distributed system.
Join us to discover how Wix has mastered the art of balancing simplicity and extensibility, and learn how the re-adoption of the modest CRUD has turbocharged their development velocity, resilience, and scalability in a high-growth environment.
Top 7 Unique WhatsApp API Benefits | Saudi ArabiaYara Milbes
Discover the transformative power of the WhatsApp API in our latest SlideShare presentation, "Top 7 Unique WhatsApp API Benefits." In today's fast-paced digital era, effective communication is crucial for both personal and professional success. Whether you're a small business looking to enhance customer interactions or an individual seeking seamless communication with loved ones, the WhatsApp API offers robust capabilities that can significantly elevate your experience.
In this presentation, we delve into the top 7 distinctive benefits of the WhatsApp API, provided by the leading WhatsApp API service provider in Saudi Arabia. Learn how to streamline customer support, automate notifications, leverage rich media messaging, run scalable marketing campaigns, integrate secure payments, synchronize with CRM systems, and ensure enhanced security and privacy.
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisGlobus
JASMIN is the UK’s high-performance data analysis platform for environmental science, operated by STFC on behalf of the UK Natural Environment Research Council (NERC). In addition to its role in hosting the CEDA Archive (NERC’s long-term repository for climate, atmospheric science & Earth observation data in the UK), JASMIN provides a collaborative platform to a community of around 2,000 scientists in the UK and beyond, providing nearly 400 environmental science projects with working space, compute resources and tools to facilitate their work. High-performance data transfer into and out of JASMIN has always been a key feature, with many scientists bringing model outputs from supercomputers elsewhere in the UK, to analyse against observational or other model data in the CEDA Archive. A growing number of JASMIN users are now realising the benefits of using the Globus service to provide reliable and efficient data movement and other tasks in this and other contexts. Further use cases involve long-distance (intercontinental) transfers to and from JASMIN, and collecting results from a mobile atmospheric radar system, pushing data to JASMIN via a lightweight Globus deployment. We provide details of how Globus fits into our current infrastructure, our experience of the recent migration to GCSv5.4, and of our interest in developing use of the wider ecosystem of Globus services for the benefit of our user community.
Unleash Unlimited Potential with One-Time Purchase
BoxLang is more than just a language; it's a community. By choosing a Visionary License, you're not just investing in your success, you're actively contributing to the ongoing development and support of BoxLang.
First Steps with Globus Compute Multi-User EndpointsGlobus
In this presentation we will share our experiences around getting started with the Globus Compute multi-user endpoint. Working with the Pharmacology group at the University of Auckland, we have previously written an application using Globus Compute that can offload computationally expensive steps in the researcher's workflows, which they wish to manage from their familiar Windows environments, onto the NeSI (New Zealand eScience Infrastructure) cluster. Some of the challenges we have encountered were that each researcher had to set up and manage their own single-user globus compute endpoint and that the workloads had varying resource requirements (CPUs, memory and wall time) between different runs. We hope that the multi-user endpoint will help to address these challenges and share an update on our progress here.
Software Engineering, Software Consulting, Tech Lead, Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Transaction, Spring MVC, OpenShift Cloud Platform, Kafka, REST, SOAP, LLD & HLD.
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteGoogle
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
👉👉 Click Here To Get More Info 👇👇
https://sumonreview.com/ai-pilot-review/
AI Pilot Review: Key Features
✅Deploy AI expert bots in Any Niche With Just A Click
✅With one keyword, generate complete funnels, websites, landing pages, and more.
✅More than 85 AI features are included in the AI pilot.
✅No setup or configuration; use your voice (like Siri) to do whatever you want.
✅You Can Use AI Pilot To Create your version of AI Pilot And Charge People For It…
✅ZERO Manual Work With AI Pilot. Never write, Design, Or Code Again.
✅ZERO Limits On Features Or Usages
✅Use Our AI-powered Traffic To Get Hundreds Of Customers
✅No Complicated Setup: Get Up And Running In 2 Minutes
✅99.99% Up-Time Guaranteed
✅30 Days Money-Back Guarantee
✅ZERO Upfront Cost
See My Other Reviews Article:
(1) TubeTrivia AI Review: https://sumonreview.com/tubetrivia-ai-review
(2) SocioWave Review: https://sumonreview.com/sociowave-review
(3) AI Partner & Profit Review: https://sumonreview.com/ai-partner-profit-review
(4) AI Ebook Suite Review: https://sumonreview.com/ai-ebook-suite-review
How Recreation Management Software Can Streamline Your Operations.pptxwottaspaceseo
Recreation management software streamlines operations by automating key tasks such as scheduling, registration, and payment processing, reducing manual workload and errors. It provides centralized management of facilities, classes, and events, ensuring efficient resource allocation and facility usage. The software offers user-friendly online portals for easy access to bookings and program information, enhancing customer experience. Real-time reporting and data analytics deliver insights into attendance and preferences, aiding in strategic decision-making. Additionally, effective communication tools keep participants and staff informed with timely updates. Overall, recreation management software enhances efficiency, improves service delivery, and boosts customer satisfaction.
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
Software Engineering, Software Consulting, Tech Lead.
Spring Boot, Spring Cloud, Spring Core, Spring JDBC, Spring Security,
Spring Transaction, Spring MVC,
Log4j, REST/SOAP WEB-SERVICES.
In the ever-evolving landscape of technology, enterprise software development is undergoing a significant transformation. Traditional coding methods are being challenged by innovative no-code solutions, which promise to streamline and democratize the software development process.
This shift is particularly impactful for enterprises, which require robust, scalable, and efficient software to manage their operations. In this article, we will explore the various facets of enterprise software development with no-code solutions, examining their benefits, challenges, and the future potential they hold.
Globus Connect Server Deep Dive - GlobusWorld 2024Globus
We explore the Globus Connect Server (GCS) architecture and experiment with advanced configuration options and use cases. This content is targeted at system administrators who are familiar with GCS and currently operate—or are planning to operate—broader deployments at their institution.
2. Eduardo Granados Ch.
Topics
Meaningful names
Use Pronounceable Names
Member Prefixes
Class and method names
Constructors
Functions
Switch Statements
Function arguments
Flag Arguments
Have no side effects
Prefer Exceptions to returning Error Codes
Comments
Format
Format
Objects and Data Structures
Exceptions vs errors
Duplicade code
SOLID
GRASP Patterns
Class
High Cohesion - Before
3. Eduardo Granados Ch.
Meaningful names
Don’t use Use
int d; // elapsed time in days
int i; // a day
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays
public List<int[]> getThem() {
List<int[]> list1 = new ArrayList<int[]>();
for (int[] x : theList)
if (x[0] == 4)
list1.add(x);
return list1;
}
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
4. Eduardo Granados Ch.
Meaningful names - Hide the magic numbers
Good Best
public List<int[]> getFlaggedCells() {
List<int[]> flaggedCells = new ArrayList<int[]>();
for (int[] cell : gameBoard)
if (cell[STATUS_VALUE] == FLAGGED)
flaggedCells.add(cell);
return flaggedCells;
}
public List<Cell> getFlaggedCells() {
List<Cell> flaggedCells = new ArrayList<Cell>();
for (Cell cell : gameBoard)
if (cell.isFlagged())
flaggedCells.add(cell);
return flaggedCells;
}
5. Eduardo Granados Ch.
Use Pronounceable Names
Don’t use Use
private Date genymdhms;
private Date modymdhms;
private final String pszqint = "102";
private Date generationTimestamp;
private Date modificationTimestamp;;
private final String recordId = "102";
6. Eduardo Granados Ch.
Member Prefixes
You also don’t need to prefix member variables with m_ anymore.
Classes and functions should be small enough that you don’t need them
Don’t use Use
public class Part {
private String m_dsc; // The textual description
void setName(String name) {
m_dsc = name;
}
}
public class Part {
String description;
void setDescription(String description) {
this.description = description;
}
}
7. Eduardo Granados Ch.
Class and method names
Classes and objects should have noun or noun phrase names like Customer, WikiPage, Account, and
AddressParser. Avoid words like Manager, Processor, Data, or Info in the name of a class. A class name
should not be a verb
Methods should have verb or verb phrase names like postPayment, deletePage, or save. Accessors,
mutators, and predicates should be named for their value and prefixed with get, set, and is according to the
javabean standard
string name = employee.getName();
customer.setName("mike");
if (paycheck.isPosted())...
8. Eduardo Granados Ch.
CONSTRUCTORS
When constructors are overloaded, use static factory methods with names that describe the arguments.
Consider enforcing their use by making the corresponding constructors private
Don’t use Use
Complex fulcrumPoint = new Complex(23.0); Complex fulcrumPoint = Complex.FromRealNumber(23.0);
10. Eduardo Granados Ch.
FUNCTIONS
1.The first rule of functions is that they should be small.
2.The second rule of functions is that they should be smaller than that. This is not an assertion that I can
justify.
FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT
WELL. THEY SHOULD DO IT ONLY.
11. Eduardo Granados Ch.
Switch Statements
public Money calculatePay(Employee e) throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
Problems:
1.it’s large, and when new employee types are
added, it will grow
2.Does more than one thing
3.It violates the Single Responsibility Principle
(SRP) because there is more than one reason for it
to change.
4.It violates the Open Closed Principle (OCP)
because it must change whenever new types are
added.
We could have isPayday(Employee e, Date date),
or deliverPay(Employee e, Money pay), etc. All of
which would have the same deleterious structure.
The solution to this problem is to bury the switch
statement in the basement of an ABSTRACT
FACTORY
12. Eduardo Granados Ch.
Switch Statements 2
public abstract class Employee {
public abstract boolean isPayday();
public abstract Money calculatePay();
public abstract void deliverPay(Money pay);
}
public interface EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws
InvalidEmployeeType;
}
public class EmployeeFactoryImpl implements EmployeeFactory {
public Employee makeEmployee(EmployeeRecord r) throws
InvalidEmployeeType {
switch (r.type) {
case COMMISSIONED:
return new CommissionedEmployee(r) ;
case HOURLY:
return new HourlyEmployee(r);
case SALARIED:
return new SalariedEmploye(r);
default:
throw new InvalidEmployeeType(r.type);
}
}
}
•Switch statements appear only once
•Used to create polymorphic objects, hidden behind
an inheritance relationship so that the rest of the
system can’t see them.
•Of course every circumstance is unique, and there
are times when I violate one or more parts of that
rule.
13. Eduardo Granados Ch.
Function arguments
The ideal number of arguments for a function is zero
Next comes one or two arguments
Three arguments should be avoided where possible
More than three (polyadic) requires very special justification and then shouldn’t be used anyway
When a function seems to need more than two or three arguments, it is likely that some of those
arguments ought to be wrapped into a class of their own:
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);
17. Eduardo Granados Ch.
Flag Arguments
Passing a boolean into a function is a truly terrible practice
Split the function into two
Don’t use Use
render(boolean isSuite); renderForSuite()
renderForSingleTest();
18. Eduardo Granados Ch.
Have No Side Effects
Your function promises to do one thing, but it also does other hidden Things
Functions should either do something or answer something, but not both
public class UserValidator {
private Cryptographer cryptographer;
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(userName);
if (user != User.NULL) {
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
}
19. Eduardo Granados Ch.
Prefer Exceptions to Returning Error Codes
Don’t use Use
if (deletePage(page) == E_OK) {
if (registry.deleteReference(page.name) == E_OK) {
if (configKeys.deleteKey(page.name.makeKey()) == E_OK) {
logger.log("page deleted");
} else {
logger.log("configKey not deleted");
}
} else {
logger.log("deleteReference from registry failed");
}
} else {
logger.log("delete failed");
return E_ERROR;
}
try {
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
logger.log(e.getMessage());
}
20. Eduardo Granados Ch.
COMENTS
The proper use of comments is to compensate for our failure to express ourself in code
Ooh, I’d better comment that!” No! You’d better clean it!
Don’t use Use
// Check to see if the employee is eligible for full benefits
if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))
if (employee.isEligibleForFullBenefits())
A comment like this can sometimes be useful, but it is better to
use the name of the function
to convey the information where possible.
// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();
Here’s a case that’s a bit better: // format matched kk:mm:ss EEE, MMM dd, yyyy
Pattern timeMatcher = Pattern.compile("d*:d*:d* w*,
w* d*, d*");
22. Eduardo Granados Ch.
COMMENTS - Clarification
Clarification: Sometimes it is just helpful to translate the meaning
assertTrue(a.compareTo(a) == 0); // a == a
assertTrue(a.compareTo(b) != 0); // a != b
assertTrue(ab.compareTo(ab) == 0); // ab == ab
Warning of Consequences: Sometimes it is useful to warn about certain consequences here is a comment
that explains why a particular test case is turned off:
// Don't run unless you
// have some time to kill.
public void _testWithReallyBigFile();
23. Eduardo Granados Ch.
FORMAT
choose a set of simple rules that govern the format of code
If you are working on a team, then the team should agree to a single set of formatting rules and all
members should comply
24. Eduardo Granados Ch.
Objects and Data Structures
Procedural Shape Polymorphic Shapes
public class Square {
public Point topLeft;
public double side;
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Circle {
public Point center;
public double radius;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Object shape) throws NoSuchShapeException {
if (shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
} else if (shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
} else if (shape instanceof Circle) {
Circle c = (Circle)shape;
return PI * c.radius * c.radius;
}
throw new NoSuchShapeException();
}
public class Square implements Shape {
private Point topLeft;
private double side;
public double area() {
return side*side;
}
}
public class Rectangle implements Shape {
private Point topLeft;
private double height;
private double width;
public double area() {
return height * width;
}
}
public class Circle implements Shape {
private Point center;
private double radius;
public final double PI = 3.141592653589793;
public double area() {
return PI * radius * radius;
}
}
25. Eduardo Granados Ch.
Objects and Data Structures
Objects expose behavior and hide data. This makes it easy to add new kinds of objects without changing
existing behaviors. It also makes it hard to add new behaviors to existing objects. Data structures expose
data and have no significant behavior
36. Eduardo Granados Ch.
SOLID
Single responsibility
A class should have only a single responsibility (i.e. only one potential change in the software's specification should be able to
affect the specification of the class)
Open-closed
software entities … should be open for extension, but closed for modification
Liskov substitution
objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program
Interface segregation
many client-specific interfaces are better than one general-purpose interface
Dependency inversion
one should “Depend upon Abstractions. Do not depend upon concretions”
38. Eduardo Granados Ch.
Class
a class should begin with a list of variables. Public static constants, if any, should come first. Then private static
variables, followed by private instance variables. There is seldom a good reason to have a public variable.
Public functions should follow the list of variables. We like to put the private utilities called by a public function right
after the public function itself. This follows the stepdown rule and helps the program read like a newspaper article.
39. Eduardo Granados Ch.
High Cohesion - Before
package literatePrimes;
public class PrintPrimes {
public static void main(String[] args) {
final int M = 1000;
final int RR = 50;
final int CC = 4;
final int WW = 10;
final int ORDMAX = 30;
int P[] = new int[M + 1];
int PAGENUMBER;
int PAGEOFFSET;
int ROWOFFSET;
int C;
int J;
int K;
boolean JPRIME;
int ORD;
int SQUARE;
int N;
int MULT[] = new int[ORDMAX + 1];
J = 1;
K = 1;
P[1] = 2;
ORD = 2;
SQUARE = 9;
while (K < M) {
do {
J = J + 2;
if (J == SQUARE) {
ORD = ORD + 1;
SQUARE = P[ORD] * P[ORD];
MULT[ORD - 1] = J;
}
N = 2;
JPRIME = true;
while (N < ORD && JPRIME) {
while (MULT[N] < J)
MULT[N] = MULT[N] + P[N] + P[N];
if (MULT[N] == J)
JPRIME = false;
N = N + 1;
}
} while (!JPRIME);
K = K + 1;
P[K] = J;
}
{
PAGENUMBER = 1;
PAGEOFFSET = 1;
while (PAGEOFFSET <= M) {
System.out.println("The First " + M +
" Prime Numbers --- Page " + PAGENUMBER);
System.out.println("");
for (ROWOFFSET = PAGEOFFSET; ROWOFFSET < PAGEOFFSET + RR;
ROWOFFSET++){
for (C = 0; C < CC;C++)
if (ROWOFFSET + C * RR <= M)
System.out.format("%10d", P[ROWOFFSET + C * RR]);
System.out.println("");
}
System.out.println("f");
PAGENUMBER = PAGENUMBER + 1;
PAGEOFFSET = PAGEOFFSET + RR * CC;
}
}
}
}
40. Eduardo Granados Ch.
High Cohesion – After (1/4)
Slit into three main responsibilities
1.The main program is contained in the PrimePrinter class all by itself. Its responsibility is to handle the execution
environment. It will change if the method of invocation changes. For example, if this program were converted to a
SOAP service, this is the class that would be affected
2.The RowColumnPagePrinter knows all about how to format a list of numbers into pages with a certain number of
rows and columns. If the formatting of the output needed changing, then this is the class that would be affected.
3.The PrimeGenerator class knows how to generate a list prime numbers. Notice that it is not meant to be
instantiated as an object. The class is just a useful scope in which its variables can be declared and kept hidden.
This class will change if the algorithm for computing prime numbers changes.
41. Eduardo Granados Ch.
High Cohesion – After (2/4)
package literatePrimes;
public class PrimePrinter {
public static void main(String[] args) {
final int NUMBER_OF_PRIMES = 1000;
int[] primes = PrimeGenerator.generate(NUMBER_OF_PRIMES);
final int ROWS_PER_PAGE = 50;
final int COLUMNS_PER_PAGE = 4;
RowColumnPagePrinter tablePrinter = new RowColumnPagePrinter(ROWS_PER_PAGE,
COLUMNS_PER_PAGE, "The First " + NUMBER_OF_PRIMES +" Prime Numbers");
tablePrinter.print(primes);
}
}
42. Eduardo Granados Ch.
High Cohesion – After (3/4)
package literatePrimes;
import java.io.PrintStream;
public class RowColumnPagePrinter {
private int rowsPerPage, columnsPerPage,numbersPerPage;
private String pageHeader;
private PrintStream printStream;
public RowColumnPagePrinter(int rowsPerPage, int columnsPerPage,
String pageHeader) {
this.rowsPerPage = rowsPerPage;
this.columnsPerPage = columnsPerPage;
this.pageHeader = pageHeader;
numbersPerPage = rowsPerPage * columnsPerPage;
printStream = System.out;
}
public void print(int data[]) {
int pageNumber = 1;
for (int firstIndexOnPage = 0; firstIndexOnPage < data.length;
firstIndexOnPage += numbersPerPage) {
int lastIndexOnPage = Math.min(firstIndexOnPage +
numbersPerPage - 1, data.length - 1);
printPageHeader(pageHeader, pageNumber);
printPage(firstIndexOnPage, lastIndexOnPage, data);
printStream.println("f");
pageNumber++;
}
}
private void printPage(int firstIndexOnPage, int lastIndexOnPage, int[] data) {
int firstIndexOfLastRowOnPage = firstIndexOnPage + rowsPerPage - 1;
for (int firstIndexInRow = firstIndexOnPage;
firstIndexInRow <= firstIndexOfLastRowOnPage;
firstIndexInRow++) {
printRow(firstIndexInRow, lastIndexOnPage, data);
printStream.println("");
}
}
private void printRow(int firstIndexInRow, int lastIndexOnPage, int[] data) {
for (int column = 0; column < columnsPerPage; column++) {
int index = firstIndexInRow + column * rowsPerPage;
if (index <= lastIndexOnPage)
printStream.format("%10d", data[index]);
}
}
private void printPageHeader(String pageHeader, int pageNumber) {
printStream.println(pageHeader + " --- Page " + pageNumber);
printStream.println("");
}
public void setOutput(PrintStream printStream) {
this.printStream = printStream;
}
}
43. Eduardo Granados Ch.
High Cohesion – After (4/4)
package literatePrimes;
import java.util.ArrayList;
public class PrimeGenerator {
private static int[] primes;
private static ArrayList<Integer> multiplesOfPrimeFactors;
protected static int[] generate(int n) {
primes = new int[n];
multiplesOfPrimeFactors = new ArrayList<Integer>();
set2AsFirstPrime();
checkOddNumbersForSubsequentPrimes();
return primes;
}
private static void set2AsFirstPrime() {
primes[0] = 2;
multiplesOfPrimeFactors.add(2);
}
private static void checkOddNumbersForSubsequentPrimes() {
int primeIndex = 1;
for (int candidate = 3; primeIndex < primes.length; candidate += 2) {
if (isPrime(candidate))
primes[primeIndex++] = candidate;
}
}
private static boolean isPrime(int candidate) {
if (isLeastRelevantMultipleOfNextLargerPrimeFactor(candidate)) {
multiplesOfPrimeFactors.add(candidate);
return false;
}
return isNotMultipleOfAnyPreviousPrimeFactor(candidate);
}
private static boolean isLeastRelevantMultipleOfNextLargerPrimeFactor(int candidate) {
int nextLargerPrimeFactor = primes[multiplesOfPrimeFactors.size()];
int leastRelevantMultiple = nextLargerPrimeFactor * nextLargerPrimeFactor;
return candidate == leastRelevantMultiple;
}
private static boolean isNotMultipleOfAnyPreviousPrimeFactor(int candidate) {
for (int n = 1; n < multiplesOfPrimeFactors.size(); n++) {
if (isMultipleOfNthPrimeFactor(candidate, n))
return false;
}
return true;
}
private static boolean isMultipleOfNthPrimeFactor(int candidate, int n) {
return candidate == smallestOddNthMultipleNotLessThanCandidate(candidate, n);
}
private static int smallestOddNthMultipleNotLessThanCandidate(int candidate, int n) {
int multiple = multiplesOfPrimeFactors.get(n);
while (multiple < candidate)
multiple += 2 * primes[n];
multiplesOfPrimeFactors.set(n, multiple);
return multiple;
}
}