Inf1-OP
Refactoring and Design Patterns Volker Seeker
School of Informatics
March 8, 2019
Inf1-OP Refactoring and Design Patterns Volker Seeker School of - - PowerPoint PPT Presentation
Inf1-OP Refactoring and Design Patterns Volker Seeker School of Informatics March 8, 2019 Refactoring Hockey Analysis Season Game -minutesPlayed:double -games:List<Game> -goalsAgainst:int -shotsOnGoalAgainst:int
Refactoring and Design Patterns Volker Seeker
School of Informatics
March 8, 2019
Game
+getShotsOnGoalAgainst():int
+getGoalsAgainst():int +getMinutesPlayed():double
Season
+getGames():List<Game>
+removeGame(Game):void +getGoalieStatistics():GoalieStatistics +addGame(Game):void
GoalieStatistics
Implement a class to calculate goalie statistics from all games in a season.
◮ Goals Against Average (GAA): Number of goals scored against a goalie divided by the number of minutes the goalie played for a season multiplied by 60 (number of minutes in a hockey game).
◮ Goals Against Average (GAA): Number of goals scored against a goalie divided by the number of minutes the goalie played for a season multiplied by 60 (number of minutes in a hockey game). GAA = 60
timeplayedmins
◮ Goals Against Average (GAA): Number of goals scored against a goalie divided by the number of minutes the goalie played for a season multiplied by 60 (number of minutes in a hockey game). GAA = 60
timeplayedmins
goal, SOG, minus the number of goals scored on a goalie) divided by the total SOG.
◮ Goals Against Average (GAA): Number of goals scored against a goalie divided by the number of minutes the goalie played for a season multiplied by 60 (number of minutes in a hockey game). GAA = 60
timeplayedmins
goal, SOG, minus the number of goals scored on a goalie) divided by the total SOG. SV % = SOG−Goals
SOG
Game
+getShotsOnGoalAgainst():int
+getGoalsAgainst():int +getMinutesPlayed():double
Season
+getGames():List<Game>
+removeGame(Game):void +getGoalieStatistics():GoalieStatistics +addGame(Game):void
GoalieStatistics
Let’s make a rough plan first!
Game
+getShotsOnGoalAgainst():int
+getGoalsAgainst():int +getMinutesPlayed():double
Season
+getGames():List<Game>
+removeGame(Game):void +getGoalieStatistics():GoalieStatistics +addGame(Game):void
GoalieStatistics
+getSavePercentage():double
+getGoalsAgainstAverage:double
Let’s make a rough plan first!
A set of unit tests is provided to check the expected behaviour
Game
+getShotsOnGoalAgainst():int
+getGoalsAgainst():int +getMinutesPlayed():double
Season
+getGames():List<Game>
+removeGame(Game):void +getGoalieStatistics():GoalieStatistics +addGame(Game):void
GoalieStatistics
+getSavePercentage():double
+getGoalsAgainstAverage:double
We use test driven development.
Game
+getShotsOnGoalAgainst():int
+getGoalsAgainst():int +getMinutesPlayed():double
Season
+getGames():List<Game>
+removeGame(Game):void +getGoalieStatistics():GoalieStatistics +addGame(Game):void
GoalieStatistics
+getSavePercentage():double
+getGoalsAgainstAverage:double
GoalieStatisticsT est
We use test driven development.
We have now successfully improved the internal structure of the code using small incremental steps whilst maintaining the original program logic.
We have now successfully improved the internal structure of the code using small incremental steps whilst maintaining the original program logic.
It is important that the expected behaviour of the code does not change during refactoring.
Source: https://dzone.com/articles/what-is-refactoring
Optimally, refactoring is part of the test driven development
Source: https://dzone.com/articles/what-is-refactoring
◮ loop splitting ◮ method extraction ◮ renaming ◮ . . .
https://www.refactoring.com/catalog/
◮ Bloaters ◮ Object-Orientation Abusers ◮ Change Preventers ◮ . . .
https://refactoring.guru/refactoring/smells
First learn your basic tools and material.
Source: https://i.kinja-img.com/gawker-media/image/upload/s–Zo3E8URT– /c scale,f auto,fl progressive,q 80,w 800/18muwoa3oozw6jpg.jpg
First learn your basic tools and material. Then build large houses ...
Source: http://hannesdorfmann.com/images/legohouse/legohouse.jpg
First learn your basic tools and material. Then build large houses ...or even cities.
Source: https://i.kinja-img.com/gawker-media/image/upload/s–uTscbBDV– /c scale,f auto,fl progressive,q 80,w 800/tu3yxy86lxwmw5vw8yeu.jpg
Source: https://www.rff.com/cloverleaf.png
◮ Creational Patterns ◮ Structural Patterns ◮ Behavioural Patterns
Problem
◮ access a resource in your program
Problem
◮ access a resource in your program → database resource
Problem
◮ access a resource in your program → database resource ◮ initialising resource access is expensive
Problem
◮ access a resource in your program → database resource ◮ initialising resource access is expensive → only one instance
Problem
◮ access a resource in your program → database resource ◮ initialising resource access is expensive → only one instance ◮ multiple classes need access
Problem
◮ access a resource in your program → database resource ◮ initialising resource access is expensive → only one instance ◮ multiple classes need access → globally available
public class Database { private final DBConnection connection; public Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public List<String> query(String q) { ... }
public class Database { private final DBConnection connection; public Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public List<String> query(String q) { ... } Globally available instance not guaranteed!
public class Database { private static Database dbase; private final DBConnection connection; public Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public List<String> query(String q) { ... } Add private static field for storing the singleton instance.
public class Database { private static Database dbase; private final DBConnection connection; public Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public static Database getInstance() { // ? } public List<String> query(String q) { ... } Declare public static creation method to access the singleton instance.
public class Database { private static Database dbase; private final DBConnection connection; public Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public static Database getInstance() { if(dbase == null) dbase = new Database(); return dbase; } public List<String> query(String q) { ... } Lazily create the instance of the singleton if necessary and return it.
public class Database { private static Database dbase; private final DBConnection connection; private Database() { connection = new DBConnection("myuser", "myhost", "mydatabase"); connection.connect(); } public static Database getInstance() { if(dbase == null) dbase = new Database(); return dbase; } public List<String> query(String q) { ... } Make the singleton constructor private.
public static void main(String[] args) { Database db = Database.getInstance(); db.query(args[0]); } In a client, use the getInstance method to access the singleton.
Problem
◮ you need to integrate a complex library into your own codebase ◮ many interdependencies between your own code and the third party code
Problem
◮ you need to integrate a complex library into your own codebase ◮ many interdependencies between your own code and the third party code What if a new version of this library is suddenly broken? What if you find a better library?
Solution
Use a facade class which provides a simple interface to the library code.
Source: https://refactoring.guru/design-patterns/facade
Problem
How to best communicate events between classes?
Source: https://refactoring.guru/design-patterns/observer
Solution
Source: https://refactoring.guru/design-patterns/observer
https://refactoring.guru/design-patterns/catalog
◮ Refactoring improves the inner structure of code using small incremental steps without changing the expected behaviour ◮ It should be part of every development process ◮ With experience, you develop a nose for code smells ◮ Design patterns are blueprints of solutions for common software engineering problems
Books
◮ Refactoring: Improving the Design of Existing Code by Martin Fowler ◮ Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Ralph Johnson, John Vlissides, Richard Helm ◮ Effective Java by Joshua Bloch
Web Resources
◮ https://www.refactoring.com/ ◮ https://dzone.com/articles/what-is-refactoring ◮ https://refactoring.guru/