├── .gitignore
├── README.md
├── maintainabilitybook.sln
├── pom.xml
└── src
├── csharp
├── Properties
│ └── AssemblyInfo.cs
├── eu
│ └── sig
│ │ └── training
│ │ ├── ch02
│ │ ├── BalancesServlet.cs
│ │ ├── BoardFactory.cs
│ │ ├── Employees.cs
│ │ ├── Level.cs
│ │ ├── LevelHelper.cs
│ │ ├── v1
│ │ │ └── BoardFactory.cs
│ │ └── v2
│ │ │ └── BoardFactory.cs
│ │ ├── ch03
│ │ ├── Flag.cs
│ │ ├── FlagFactory.cs
│ │ ├── FlagFactoryOops.cs
│ │ ├── FlagFactoryWithMap.cs
│ │ ├── JenkinsUser.cs
│ │ ├── Nationality.cs
│ │ ├── binarytree
│ │ │ ├── BinaryTreeNode.cs
│ │ │ ├── TreeException.cs
│ │ │ ├── v1
│ │ │ │ └── BinaryTreeSearch.cs
│ │ │ ├── v2
│ │ │ │ └── BinaryTreeSearch.cs
│ │ │ └── v3
│ │ │ │ └── BinaryTreeSearch.cs
│ │ └── withmapandtypes
│ │ │ ├── BelgianFlag.cs
│ │ │ ├── DefaultFlag.cs
│ │ │ ├── DutchFlag.cs
│ │ │ ├── FlagFactory.cs
│ │ │ ├── FrenchFlag.cs
│ │ │ ├── GermanFlag.cs
│ │ │ ├── IFlag.cs
│ │ │ └── ItalianFlag.cs
│ │ ├── ch04
│ │ ├── BusinessException.cs
│ │ ├── Clones.cs
│ │ ├── Money.cs
│ │ ├── v1
│ │ │ ├── Accounts.cs
│ │ │ ├── CheckingAccount.cs
│ │ │ ├── SavingsAccount.cs
│ │ │ └── Transfer.cs
│ │ ├── v2
│ │ │ ├── Accounts.cs
│ │ │ ├── CheckingAccount.cs
│ │ │ ├── SavingsAccount.cs
│ │ │ └── Transfer.cs
│ │ ├── v3
│ │ │ ├── Account.cs
│ │ │ ├── Accounts.cs
│ │ │ ├── CheckingAccount.cs
│ │ │ ├── SavingsAccount.cs
│ │ │ └── Transfer.cs
│ │ └── v4
│ │ │ ├── Account.cs
│ │ │ ├── Accounts.cs
│ │ │ └── Transfer.cs
│ │ ├── ch05
│ │ ├── boardpanel
│ │ │ ├── v1
│ │ │ │ └── BoardPanel.cs
│ │ │ ├── v2
│ │ │ │ ├── BoardPanel.cs
│ │ │ │ └── Rectangle.cs
│ │ │ └── v3
│ │ │ │ └── BoardPanel.cs
│ │ ├── buildandsendmail
│ │ │ ├── v1
│ │ │ │ └── BuildAndSendMail.cs
│ │ │ └── v2
│ │ │ │ └── BuildAndSendMail.cs
│ │ └── chartlib
│ │ │ ├── v1
│ │ │ └── Charts.cs
│ │ │ └── v2
│ │ │ └── BarChart.cs
│ │ ├── ch06
│ │ ├── advanceddigitalcamera
│ │ │ ├── DigitalCamera.cs
│ │ │ └── Video.cs
│ │ ├── digitalcamera
│ │ │ ├── DigitalCamera.cs
│ │ │ └── SmartphoneApp.cs
│ │ ├── simpledigitalcamera
│ │ │ ├── DigitalCamera.cs
│ │ │ ├── ISimpleDigitalCamera.cs
│ │ │ ├── SDK.cs
│ │ │ └── SmartphoneApp.cs
│ │ └── userservice
│ │ │ ├── NotificationType.cs
│ │ │ ├── User.cs
│ │ │ ├── UserInfo.cs
│ │ │ ├── splitted
│ │ │ ├── UserBlockService.cs
│ │ │ ├── UserNotificationService.cs
│ │ │ └── UserService.cs
│ │ │ ├── v1
│ │ │ ├── UserRestAPI.cs
│ │ │ └── UserService.cs
│ │ │ ├── v2
│ │ │ ├── NotificationRestAPI.cs
│ │ │ └── UserService.cs
│ │ │ └── v3
│ │ │ └── UserService.cs
│ │ ├── ch07
│ │ ├── AWSCloudServerFactory.cs
│ │ ├── AWSCloudStorage.cs
│ │ ├── AWSComputeServer.cs
│ │ ├── AWSDatabaseServer.cs
│ │ ├── ApplicationLauncher.cs
│ │ ├── AzureCloudServerFactory.cs
│ │ ├── AzureCloudStorage.cs
│ │ ├── AzureComputeServer.cs
│ │ ├── AzureDatabaseServer.cs
│ │ ├── ICloudServer.cs
│ │ ├── ICloudServerFactory.cs
│ │ └── ICloudStorage.cs
│ │ ├── ch10
│ │ ├── PerfectPicture.cs
│ │ └── Program.cs
│ │ └── ch11
│ │ ├── DeadCode.cs
│ │ ├── MagicConstants.cs
│ │ └── StandardContext.cs
├── maintainabilitybook.csproj
└── packages.config
├── java
└── eu
│ └── sig
│ └── training
│ ├── ch02
│ ├── BalancesServlet.java
│ ├── BoardFactory.java
│ ├── Employees.java
│ ├── Level.java
│ ├── LevelHelper.java
│ ├── v1
│ │ └── BoardFactory.java
│ └── v2
│ │ └── BoardFactory.java
│ ├── ch03
│ ├── Flag.java
│ ├── FlagFactory.java
│ ├── FlagFactoryOops.java
│ ├── FlagFactoryWithMap.java
│ ├── JenkinsUser.java
│ ├── Nationality.java
│ ├── binarytree
│ │ ├── BinaryTreeNode.java
│ │ ├── TreeException.java
│ │ ├── v1
│ │ │ └── BinaryTreeSearch.java
│ │ ├── v2
│ │ │ └── BinaryTreeSearch.java
│ │ └── v3
│ │ │ └── BinaryTreeSearch.java
│ └── withmapandtypes
│ │ ├── BelgianFlag.java
│ │ ├── DefaultFlag.java
│ │ ├── DutchFlag.java
│ │ ├── Flag.java
│ │ ├── FlagFactory.java
│ │ ├── FrenchFlag.java
│ │ ├── GermanFlag.java
│ │ └── ItalianFlag.java
│ ├── ch04
│ ├── BusinessException.java
│ ├── Clones.java
│ ├── Money.java
│ ├── v1
│ │ ├── Accounts.java
│ │ ├── CheckingAccount.java
│ │ ├── SavingsAccount.java
│ │ └── Transfer.java
│ ├── v2
│ │ ├── Accounts.java
│ │ ├── CheckingAccount.java
│ │ ├── SavingsAccount.java
│ │ └── Transfer.java
│ ├── v3
│ │ ├── Account.java
│ │ ├── Accounts.java
│ │ ├── CheckingAccount.java
│ │ ├── SavingsAccount.java
│ │ └── Transfer.java
│ └── v4
│ │ ├── Account.java
│ │ ├── Accounts.java
│ │ └── Transfer.java
│ ├── ch05
│ ├── boardpanel
│ │ ├── v1
│ │ │ └── BoardPanel.java
│ │ ├── v2
│ │ │ ├── BoardPanel.java
│ │ │ └── Rectangle.java
│ │ └── v3
│ │ │ └── BoardPanel.java
│ ├── buildandsendmail
│ │ ├── v1
│ │ │ └── BuildAndSendMail.java
│ │ └── v2
│ │ │ └── BuildAndSendMail.java
│ └── chartlib
│ │ ├── v1
│ │ └── Charts.java
│ │ └── v2
│ │ └── BarChart.java
│ ├── ch06
│ ├── advanceddigitalcamera
│ │ ├── DigitalCamera.java
│ │ └── Video.java
│ ├── digitalcamera
│ │ ├── DigitalCamera.java
│ │ └── SmartphoneApp.java
│ ├── simpledigitalcamera
│ │ ├── DigitalCamera.java
│ │ ├── SDK.java
│ │ ├── SimpleDigitalCamera.java
│ │ └── SmartphoneApp.java
│ └── userservice
│ │ ├── NotificationType.java
│ │ ├── User.java
│ │ ├── UserInfo.java
│ │ ├── splitted
│ │ ├── UserBlockService.java
│ │ ├── UserNotificationService.java
│ │ └── UserService.java
│ │ ├── v1
│ │ ├── UserRestAPI.java
│ │ └── UserService.java
│ │ ├── v2
│ │ ├── NotificationRestAPI.java
│ │ └── UserService.java
│ │ └── v3
│ │ └── UserService.java
│ ├── ch07
│ ├── AWSCloudServerFactory.java
│ ├── AWSCloudStorage.java
│ ├── AWSComputeServer.java
│ ├── AWSDatabaseServer.java
│ ├── ApplicationLauncher.java
│ ├── AzureCloudServerFactory.java
│ ├── AzureCloudStorage.java
│ ├── AzureComputeServer.java
│ ├── AzureDatabaseServer.java
│ ├── CloudServer.java
│ ├── CloudServerFactory.java
│ └── CloudStorage.java
│ ├── ch10
│ ├── PerfectPicture.java
│ └── Program.java
│ └── ch11
│ ├── DeadCode.java
│ ├── MagicConstants.java
│ ├── PluginManager.java
│ ├── StandardContext.java
│ └── ValuableVsNonValuableComments.java
└── test
├── csharp
├── Properties
│ └── AssemblyInfo.cs
├── eu
│ └── sig
│ │ └── training
│ │ ├── ch03
│ │ ├── FlagFactoryWithMapTest.cs
│ │ ├── FlagsTest.cs
│ │ ├── binarytree
│ │ │ └── BinaryTreeSearchTest.cs
│ │ └── withmapandtypes
│ │ │ └── FlagsTest.cs
│ │ ├── ch04
│ │ ├── v1
│ │ │ └── AccountsTest.cs
│ │ ├── v3
│ │ │ ├── CheckingAccountTest.cs
│ │ │ └── SavingsAccountTest.cs
│ │ └── v4
│ │ │ └── AccountsTest.cs
│ │ ├── ch06
│ │ └── userservice
│ │ │ ├── v1
│ │ │ └── UserControllerTest.cs
│ │ │ └── v2
│ │ │ └── NotificationControllerTest.cs
│ │ └── ch10
│ │ ├── PerfectPictureMockTest.cs
│ │ └── PerfectPictureTest.cs
├── maintainabilitybooktests.csproj
└── packages.config
├── java
└── eu
│ └── sig
│ └── training
│ ├── ch03
│ ├── FlagFactoryWithMapTest.java
│ ├── FlagsTest.java
│ └── binarytree
│ │ └── BinaryTreeSearchTest.java
│ ├── ch04
│ ├── v1
│ │ └── AccountsTest.java
│ ├── v3
│ │ ├── CheckingAccountTest.java
│ │ └── SavingsAccountTest.java
│ └── v4
│ │ └── AccountsTest.java
│ └── ch10
│ ├── PerfectPictureMockTest.java
│ └── PerfectPictureTest.java
└── resources
├── VanGoghStarryNight.jpg
└── VanGoghSunflowers.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .classpath
3 | .project
4 | .settings
5 | *.userprefs
6 | packages
7 | src/csharp/bin
8 | src/csharp/obj
9 | src/test/csharp/bin
10 | src/test/csharp/obj
11 | TestResult.xml
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Building Maintainable Software
2 | ==========
3 |
4 | This is the example code that accompanies _Building Maintainable Software: Ten Guidelines for Future-Proof Code_ by Joost Visser.
5 |
6 | There are currently two editions of _Building Maintainable Software_:
7 | - The Java edition (ISBN print: 978-1-4919-5352-5, ISBN eBook: 978-1-4919-5348-8), available [at the O'Reilly webshop](http://shop.oreilly.com/product/0636920049159.do) and [at Amazon](http://www.amazon.com/Building-Maintainable-Software-Java-Edition-ebook/dp/B01B6WS86I).
8 | - The C# edition, currently submitted as a manuscript to O'Reilly Media.
9 |
10 | [Training videos](http://oreil.ly/1OVw1PM) are also available via O'Reilly Media.
11 |
12 | Both editions are the same except for the language of the code snippets and a bit of language-specific terminology (e.g., 'Eclipse' in the Java edition is 'Visual Studio' in the C# edition).
13 |
14 | Click the Download Zip button to the right to download example code.
15 |
16 | See an error? Report it [here](http://oreilly.com/catalog/errata.csp?isbn=9781491940662) for the Java edition, or simply fork and send us a pull request.
17 |
18 | About The Example Code
19 | -----------
20 |
21 | The example code of the Java edition lives in `src/java` and `src/test/java`. The example code of the C# edition lives in `src/csharp` and `src/test/csharp`. Every `.java` file in `src/java` has a `.cs` file with the same name in `src/csharp` and the other way around. The same is true for the contents of the `src/test` directories.
22 |
23 | For the Java code, there is a `pom.xml` file in the root of this repository. This allows compiling the Java source files and running the unit tests using [Maven](https://maven.apache.org) by executing `mvn test`.
24 |
25 | For the C# code, there is a Visual Studio Solution file in the root of this repository, which references two projects (see the `.csproj` files in `src/csharp` and `src/test/csharp`). We compile the C# code and run the unit tests regularly using [Mono](http://www.mono-project.com) on MacOS and occasionally using Visual Studio.
26 |
27 | Both the Java and the C# editions have been written using O'Reilly's [Atlas](https://atlas.oreilly.com) platform in the [AsciiDoc](http://asciidoc.org) markup language. All code snippets displayed in the books are taken directly from this example code. The parts included in the books are between Java and C# comments of the form `// tag::NameOfTag[]` and `// end::NameOfTag[]`. All code not between such comments is just there to make everything compile and pass unit tests.
28 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 | eu.sig.training
6 | maintainabilitybook
7 | 0.1-SNAPSHOT
8 |
9 | Software Improvement Group
10 | http://www.sig.eu
11 |
12 |
13 | git@git.atlas.oreilly.com:oreillymedia/sig-project.git
14 |
15 |
16 |
17 | junit
18 | junit
19 | 4.12
20 | test
21 |
22 |
23 | javax.servlet
24 | javax.servlet-api
25 | 3.1.0
26 |
27 |
28 | org.mockito
29 | mockito-core
30 | 1.10.19
31 | test
32 |
33 |
34 | javax.ws.rs
35 | javax.ws.rs-api
36 | 2.0.1
37 |
38 |
39 | org.apache.httpcomponents
40 | httpclient
41 | 4.5.1
42 |
43 |
44 |
45 | ${basedir}/src/java
46 |
47 |
48 | org.apache.maven.plugins
49 | maven-compiler-plugin
50 | 3.3
51 |
52 | 1.7
53 | 1.7
54 |
55 |
56 |
57 | org.apache.maven.plugins
58 | maven-eclipse-plugin
59 | 2.10
60 |
61 | ${basedir}
62 | file:///${basedir}/java_eclipseformat.xml
63 |
64 |
65 |
66 | org.apache.maven.plugins
67 | maven-surefire-plugin
68 | 2.18.1
69 |
70 |
71 | **/v1/AccountsTest.java
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | org.apache.maven.plugins
81 | maven-pmd-plugin
82 | 3.5
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/src/csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | // Information about this assembly is defined by the following attributes.
3 | // Change them to the values specific to your project.
4 |
5 | [assembly: AssemblyTitle ("maintainabilitybook")]
6 | [assembly: AssemblyDescription ("")]
7 | [assembly: AssemblyConfiguration ("")]
8 | [assembly: AssemblyCompany ("")]
9 | [assembly: AssemblyProduct ("")]
10 | [assembly: AssemblyCopyright("Software Improvement Group")]
11 | [assembly: AssemblyTrademark ("")]
12 | [assembly: AssemblyCulture ("")]
13 |
14 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
15 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
16 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
17 |
18 | [assembly: AssemblyVersion ("1.0.*")]
19 |
20 | // The following attributes are used to specify the signing key for the assembly,
21 | // if desired. See the Mono documentation for more information about signing.
22 |
23 | //[assembly: AssemblyDelaySign(false)]
24 | //[assembly: AssemblyKeyFile("")]
25 |
26 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/BalancesServlet.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web;
3 | using System.Data;
4 | using System.Data.SqlClient;
5 | using System.Configuration;
6 |
7 | namespace eu.sig.training.ch02
8 | {
9 | public class BalancesServlet
10 | {
11 | // Visual Studio Code Analysis is right in pointing out that the following method has
12 | // security flaws. However, that's beside the point for this example.
13 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities")]
14 | // tag::doGet[]
15 | public void DoGet(HttpRequest req, HttpResponse resp)
16 | {
17 | resp.ContentType = "application/json";
18 | string command = "SELECT account, balance " +
19 | "FROM ACCTS WHERE id=" + req.Params[
20 | ConfigurationManager.AppSettings["request.parametername"]];
21 | SqlDataAdapter dataAdapter = new SqlDataAdapter(command,
22 | ConfigurationManager.AppSettings["handler.serverstring"]);
23 | DataSet dataSet = new DataSet();
24 | dataAdapter.Fill(dataSet, "ACCTS");
25 | DataTable dataTable = dataSet.Tables[0];
26 | try
27 | {
28 | float totalBalance = 0;
29 | int rowNum = 0;
30 | resp.Write("{\"balances\":[");
31 | while (dataTable.Rows.GetEnumerator().MoveNext())
32 | {
33 | rowNum++;
34 | DataRow results = (DataRow)dataTable.Rows.GetEnumerator().Current;
35 | // Assuming result is 9-digit bank account number,
36 | // validate with 11-test:
37 | int sum = 0;
38 | for (int i = 0; i < ((string)results["account"]).Length; i++)
39 | {
40 | sum = sum + (9 - i) *
41 | (int)Char.GetNumericValue(((string)results["account"])[i]);
42 | }
43 | if (sum % 11 == 0)
44 | {
45 | totalBalance += (float)results["balance"];
46 | resp.Write($"{{\"{results["account"]}\":{results["balance"]}}}");
47 | }
48 | if (rowNum == dataTable.Rows.Count)
49 | {
50 | resp.Write("],\n");
51 | }
52 | else
53 | {
54 | resp.Write(",");
55 | }
56 | }
57 | resp.Write($"\"total\":{totalBalance}}}\n");
58 | }
59 | catch (SqlException e)
60 | {
61 | Console.WriteLine($"SQL exception: {e.Message}");
62 | }
63 | }
64 | // end::doGet[]
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/BoardFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace eu.sig.training.ch02
4 | {
5 | public class BoardFactory
6 | {
7 | // tag::createBoard[]
8 | public Board CreateBoard(Square[,] grid)
9 | {
10 | Debug.Assert(grid != null);
11 |
12 | Board board = new Board(grid);
13 |
14 | int width = board.Width;
15 | int height = board.Height;
16 | for (int x = 0; x < width; x++)
17 | {
18 | for (int y = 0; y < height; y++)
19 | {
20 | Square square = grid[x, y];
21 | foreach (Direction dir in Direction.Values)
22 | {
23 | int dirX = (width + x + dir.DeltaX) % width;
24 | int dirY = (height + y + dir.DeltaY) % height;
25 | Square neighbour = grid[dirX, dirY];
26 | square.Link(neighbour, dir);
27 | }
28 | }
29 | }
30 |
31 | return board;
32 | }
33 | // end::createBoard[]
34 | }
35 |
36 | public class Board
37 | {
38 | public Board(Square[,] grid) { }
39 |
40 | public int Width { get; set; }
41 |
42 | public int Height { get; set; }
43 | }
44 |
45 | public class Square
46 | {
47 | public void Link(Square neighbour, Direction dir) { }
48 | }
49 |
50 | public class Direction
51 | {
52 |
53 | public static Direction[] Values { get; set; }
54 |
55 | public int DeltaY { get; set; }
56 |
57 | public int DeltaX { get; set; }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/Employees.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch02
4 | {
5 | public static class Employees
6 | {
7 | // tag::printDepartmentEmployees[]
8 | public static void PrintDepartmentEmployees(string department)
9 | {
10 | Query q = new Query();
11 | foreach (Employee e in q.AddColumn("FamilyName")
12 | .AddColumn("Initials")
13 | .AddColumn("GivenName")
14 | .AddColumn("AddressLine1")
15 | .AddColumn("ZIPcode")
16 | .AddColumn("City")
17 | .AddTable("EMPLOYEES")
18 | .AddWhere($"EmployeeDep='{department}'")
19 | .Execute())
20 | {
21 | Console.WriteLine($@"
22 | {e.FamilyName}, {e.Initials}
" +
23 | "{e.AddressLine1}
{e.ZipCode}{e.City}
");
24 | }
25 | }
26 | // end::printDepartmentEmployees[]
27 | }
28 |
29 | class Query
30 | {
31 |
32 | public Query AddColumn(string s)
33 | {
34 | return null;
35 | }
36 |
37 | public Employee[] Execute()
38 | {
39 | return null;
40 | }
41 |
42 | public Query AddWhere(string s)
43 | {
44 | return null;
45 | }
46 |
47 | public Query AddTable(string s)
48 | {
49 | return null;
50 | }
51 | }
52 |
53 | class Employee
54 | {
55 |
56 | public string FamilyName { get; set; }
57 |
58 | public string AddressLine1 { get; set; }
59 |
60 | public string ZipCode { get; set; }
61 |
62 | public string City { get; set; }
63 |
64 | public string Initials { get; set; }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/Level.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch02
4 | {
5 |
6 | public class Level
7 | {
8 | private bool inProgress;
9 | private readonly IList observers;
10 |
11 | Level(IList observers)
12 | {
13 | this.observers = observers;
14 | }
15 |
16 | // tag::start[]
17 | public void Start()
18 | {
19 | if (inProgress)
20 | {
21 | return;
22 | }
23 | inProgress = true;
24 | // Update observers if player died:
25 | if (!IsAnyPlayerAlive())
26 | {
27 | foreach (LevelObserver o in observers)
28 | {
29 | o.LevelLost();
30 | }
31 | }
32 | // Update observers if all pellets eaten:
33 | if (RemainingPellets() == 0)
34 | {
35 | foreach (LevelObserver o in observers)
36 | {
37 | o.LevelWon();
38 | }
39 | }
40 | }
41 | // end::start[]
42 |
43 | // tag::updateObservers[]
44 | private void UpdateObservers()
45 | {
46 | // Update observers if player died:
47 | if (!IsAnyPlayerAlive())
48 | {
49 | foreach (LevelObserver o in observers)
50 | {
51 | o.LevelLost();
52 | }
53 | }
54 | // Update observers if all pellets eaten:
55 | if (RemainingPellets() == 0)
56 | {
57 | foreach (LevelObserver o in observers)
58 | {
59 | o.LevelWon();
60 | }
61 | }
62 | }
63 | // end::updateObservers[]
64 |
65 | // tag::updateObserversPlayerDied[]
66 | private void UpdateObserversPlayerDied()
67 | {
68 | if (!IsAnyPlayerAlive())
69 | {
70 | foreach (LevelObserver o in observers)
71 | {
72 | o.LevelLost();
73 | }
74 | }
75 | }
76 |
77 | // end::updateObserversPlayerDied[]
78 |
79 | // tag::updateObserversPelletsEaten[]
80 | private void UpdateObserversPelletsEaten()
81 | {
82 | if (RemainingPellets() == 0)
83 | {
84 | foreach (LevelObserver o in observers)
85 | {
86 | o.LevelWon();
87 | }
88 | }
89 | }
90 | // end::updateObserversPelletsEaten[]
91 |
92 | private int RemainingPellets()
93 | {
94 | return 0;
95 | }
96 |
97 | private bool IsAnyPlayerAlive()
98 | {
99 | return false;
100 | }
101 | }
102 |
103 | class LevelObserver
104 | {
105 | public void LevelLost() { }
106 | public void LevelWon() { }
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/LevelHelper.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch02
2 | {
3 |
4 | public class LevelHelper
5 | {
6 | private bool inProgress;
7 |
8 | // tag::firstStepStart[]
9 | public void Start()
10 | {
11 | if (inProgress)
12 | {
13 | return;
14 | }
15 | inProgress = true;
16 | }
17 | // end::firstStepStart[]
18 | }
19 |
20 | public class ExtractMethod
21 | {
22 | private bool inProgress;
23 |
24 | // tag::extractMethodStart[]
25 | public void Start()
26 | {
27 | if (inProgress)
28 | {
29 | return;
30 | }
31 | inProgress = true;
32 | UpdateObservers();
33 | }
34 | // end::extractMethodStart[]
35 |
36 | // tag::updateObservers[]
37 | public void UpdateObservers()
38 | {
39 | UpdateObserversPlayerDied();
40 | UpdateObserversPelletsEaten();
41 | }
42 | // end::updateObservers[]
43 |
44 | private void UpdateObserversPlayerDied() { }
45 |
46 | private void UpdateObserversPelletsEaten() { }
47 |
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/v1/BoardFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace eu.sig.training.ch02.v1
4 | {
5 | public class BoardFactory
6 | {
7 | // tag::createBoard[]
8 | public Board CreateBoard(Square[,] grid)
9 | {
10 | Debug.Assert(grid != null);
11 |
12 | Board board = new Board(grid);
13 |
14 | int width = board.Width;
15 | int height = board.Height;
16 | for (int x = 0; x < width; x++)
17 | {
18 | for (int y = 0; y < height; y++)
19 | {
20 | Square square = grid[x, y];
21 | foreach (Direction dir in Direction.Values)
22 | {
23 | SetLink(square, dir, x, y, width, height, grid);
24 | }
25 | }
26 | }
27 |
28 | return board;
29 | }
30 | // end::createBoard[]
31 |
32 | // tag::setLink[]
33 | private void SetLink(Square square, Direction dir, int x, int y,
34 | int width, int height, Square[,] grid)
35 | {
36 | int dirX = (width + x + dir.DeltaX) % width;
37 | int dirY = (height + y + dir.DeltaY) % height;
38 | Square neighbour = grid[dirX, dirY];
39 | square.Link(neighbour, dir);
40 | }
41 | // end::setLink[]
42 | }
43 |
44 | public class Board
45 | {
46 | public Board(Square[,] grid) { }
47 |
48 | public int Width { get; set; }
49 | public int Height { get; set; }
50 | }
51 |
52 | public class Square
53 | {
54 | public void Link(Square neighbour, Direction dir) { }
55 | }
56 |
57 | public class Direction
58 | {
59 |
60 | public static Direction[] Values { get; set; }
61 |
62 | public int DeltaY { get; set; }
63 |
64 | public int DeltaX { get; set; }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch02/v2/BoardFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace eu.sig.training.ch02.v2
4 | {
5 | public class BoardFactory
6 | {
7 | // tag::createBoard[]
8 | public Board CreateBoard(Square[,] grid)
9 | {
10 | return new BoardCreator(grid).Create();
11 | }
12 | // end::createBoard[]
13 | }
14 |
15 | // tag::BoardCreator[]
16 | internal class BoardCreator
17 | {
18 | private Square[,] grid;
19 | private Board board;
20 | private int width;
21 | private int height;
22 |
23 | internal BoardCreator(Square[,] grid)
24 | {
25 | Debug.Assert(grid != null);
26 | this.grid = grid;
27 | this.board = new Board(grid);
28 | this.width = board.Width;
29 | this.height = board.Height;
30 | }
31 |
32 | internal Board Create()
33 | {
34 | for (int x = 0; x < width; x++)
35 | {
36 | for (int y = 0; y < height; y++)
37 | {
38 | Square square = grid[x, y];
39 | foreach (Direction dir in Direction.Values)
40 | {
41 | SetLink(square, dir, x, y);
42 | }
43 | }
44 | }
45 | return this.board;
46 | }
47 |
48 | private void SetLink(Square square, Direction dir, int x, int y)
49 | {
50 | int dirX = (width + x + dir.DeltaX) % width;
51 | int dirY = (height + y + dir.DeltaY) % height;
52 | Square neighbour = grid[dirX, dirY];
53 | square.Link(neighbour, dir);
54 | }
55 | }
56 |
57 | // end::BoardCreator[]
58 |
59 | public class Board
60 | {
61 | public Board(Square[,] grid)
62 | {
63 | }
64 |
65 | public int Width { get; set; }
66 |
67 | public int Height { get; set; }
68 | }
69 |
70 | public class Square
71 | {
72 | public void Link(Square neighbour, Direction dir)
73 | {
74 | }
75 | }
76 |
77 | public class Direction
78 | {
79 | public static Direction[] Values { get; set; }
80 |
81 | public int DeltaY { get; set; }
82 |
83 | public int DeltaX { get; set; }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/Flag.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 |
4 | namespace eu.sig.training.ch03
5 | {
6 |
7 | public class Flag
8 | {
9 | public IList Colors { get; }
10 |
11 | public Flag(params Color[] colors)
12 | {
13 | Colors = new List(colors);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/FlagFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03
5 | {
6 |
7 | public class FlagFactory
8 | {
9 | // tag::getFlag[]
10 | public IList GetFlagColors(Nationality nationality)
11 | {
12 | List result;
13 | switch (nationality)
14 | {
15 | case Nationality.DUTCH:
16 | result = new List { Color.Red, Color.White, Color.Blue };
17 | break;
18 | case Nationality.GERMAN:
19 | result = new List { Color.Black, Color.Red, Color.Yellow };
20 | break;
21 | case Nationality.BELGIAN:
22 | result = new List { Color.Black, Color.Yellow, Color.Red };
23 | break;
24 | case Nationality.FRENCH:
25 | result = new List { Color.Blue, Color.White, Color.Red };
26 | break;
27 | case Nationality.ITALIAN:
28 | result = new List { Color.Green, Color.White, Color.Red };
29 | break;
30 | case Nationality.UNCLASSIFIED:
31 | default:
32 | result = new List { Color.Gray };
33 | break;
34 | }
35 | return result;
36 | }
37 | // end::getFlag[]
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/FlagFactoryOops.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03
5 | {
6 | public class FlagFactoryOops
7 | {
8 | public IList GetFlagColors(Nationality nationality)
9 | {
10 | List result;
11 | switch (nationality)
12 | {
13 | // tag::getFlag[]
14 | case Nationality.DUTCH:
15 | result = new List { Color.Red, Color.White, Color.Blue };
16 | // end::getFlag[]
17 | break;
18 | // tag::getFlag[]
19 | case Nationality.LUXEMBOURGER:
20 | result = new List { Color.Red, Color.White, Color.LightBlue };
21 | break;
22 | case Nationality.GERMAN:
23 | // end::getFlag[]
24 | result = new List { Color.Black, Color.Red, Color.Yellow };
25 | break;
26 | case Nationality.BELGIAN:
27 | result = new List { Color.Black, Color.Yellow, Color.Red };
28 | break;
29 | case Nationality.FRENCH:
30 | result = new List { Color.Blue, Color.White, Color.Red };
31 | break;
32 | case Nationality.ITALIAN:
33 | result = new List { Color.Green, Color.White, Color.Red };
34 | break;
35 | case Nationality.UNCLASSIFIED:
36 | default:
37 | result = new List { Color.Gray };
38 | break;
39 | }
40 | return result;
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/FlagFactoryWithMap.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 |
4 | namespace eu.sig.training.ch03
5 | {
6 |
7 | public class FlagFactoryWithMap
8 | {
9 |
10 | // tag::getFlag[]
11 | private static Dictionary> FLAGS =
12 | new Dictionary>();
13 |
14 | static FlagFactoryWithMap()
15 | {
16 | FLAGS[Nationality.DUTCH] = new List{ Color.Red, Color.White,
17 | Color.Blue };
18 | FLAGS[Nationality.GERMAN] = new List{ Color.Black, Color.Red,
19 | Color.Yellow };
20 | FLAGS[Nationality.BELGIAN] = new List{ Color.Black, Color.Yellow,
21 | Color.Red };
22 | FLAGS[Nationality.FRENCH] = new List{ Color.Blue, Color.White,
23 | Color.Red };
24 | FLAGS[Nationality.ITALIAN] = new List{ Color.Green, Color.White,
25 | Color.Red };
26 | }
27 |
28 | public IList GetFlagColors(Nationality nationality)
29 | {
30 | IList colors = FLAGS[nationality];
31 | return colors ?? new List { Color.Gray };
32 | }
33 | // end::getFlag[]
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/Nationality.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch03
2 | {
3 |
4 | public enum Nationality
5 | {
6 | DUTCH,
7 | GERMAN,
8 | BELGIAN,
9 | FRENCH,
10 | ITALIAN,
11 | LUXEMBOURGER,
12 | UNCLASSIFIED
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/binarytree/BinaryTreeNode.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch03.binarytree
4 | {
5 |
6 | public class BinaryTreeNode where T : IComparable
7 | {
8 | public T Value { get; set; }
9 | public BinaryTreeNode Left { get; set; }
10 | public BinaryTreeNode Right { get; set; }
11 |
12 | public BinaryTreeNode(T value)
13 | {
14 | this.Value = value;
15 | }
16 |
17 | public void Insert(T value)
18 | {
19 | if (value.CompareTo(this.Value) < 0)
20 | {
21 | if (Left != null)
22 | {
23 | Left.Insert(value);
24 | }
25 | else
26 | {
27 | Left = new BinaryTreeNode(value);
28 | }
29 | }
30 | else
31 | {
32 | if (Right != null)
33 | {
34 | Right.Insert(value);
35 | }
36 | else
37 | {
38 | Right = new BinaryTreeNode(value);
39 | }
40 | }
41 | }
42 |
43 | public bool IsLeaf()
44 | {
45 | return Left == null && Right == null;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/binarytree/TreeException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch03.binarytree
4 | {
5 | [Serializable]
6 | public class TreeException : SystemException
7 | {
8 | public TreeException(string msg) : base(msg)
9 | {
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/binarytree/v1/BinaryTreeSearch.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch03.binarytree.v1
2 | {
3 |
4 | public class BinaryTreeSearch
5 | {
6 |
7 | // tag::calculateDepth[]
8 | public static int CalculateDepth(BinaryTreeNode t, int n)
9 | {
10 | int depth = 0;
11 | if (t.Value == n)
12 | {
13 | return depth;
14 | }
15 | else
16 | {
17 | if (n < t.Value)
18 | {
19 | BinaryTreeNode left = t.Left;
20 | if (left == null)
21 | {
22 | throw new TreeException("Value not found in tree!");
23 | }
24 | else
25 | {
26 | return 1 + CalculateDepth(left, n);
27 | }
28 | }
29 | else
30 | {
31 | BinaryTreeNode right = t.Right;
32 | if (right == null)
33 | {
34 | throw new TreeException("Value not found in tree!");
35 | }
36 | else
37 | {
38 | return 1 + CalculateDepth(right, n);
39 | }
40 | }
41 | }
42 | }
43 | // end::calculateDepth[]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/binarytree/v2/BinaryTreeSearch.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch03.binarytree.v2
2 | {
3 |
4 | public class BinaryTreeSearch
5 | {
6 |
7 | // tag::calculateDepth[]
8 | public static int CalculateDepth(BinaryTreeNode t, int n)
9 | {
10 | int depth = 0;
11 | if (t.Value == n)
12 | {
13 | return depth;
14 | }
15 | if ((n < t.Value) && (t.Left != null))
16 | {
17 | return 1 + CalculateDepth(t.Left, n);
18 | }
19 | if ((n > t.Value) && (t.Right != null))
20 | {
21 | return 1 + CalculateDepth(t.Right, n);
22 | }
23 | throw new TreeException("Value not found in tree!");
24 | }
25 | // end::calculateDepth[]
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/binarytree/v3/BinaryTreeSearch.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch03.binarytree.v3
2 | {
3 |
4 | public class BinaryTreeSearch
5 | {
6 |
7 | // tag::calculateDepth[]
8 | public static int CalculateDepth(BinaryTreeNode t, int n)
9 | {
10 | int depth = 0;
11 | if (t.Value == n)
12 | {
13 | return depth;
14 | }
15 | else
16 | {
17 | return TraverseByValue(t, n);
18 | }
19 | }
20 |
21 | private static int TraverseByValue(BinaryTreeNode t, int n)
22 | {
23 | BinaryTreeNode childNode = GetChildNode(t, n);
24 | if (childNode == null)
25 | {
26 | throw new TreeException("Value not found in tree!");
27 | }
28 | else
29 | {
30 | return 1 + CalculateDepth(childNode, n);
31 | }
32 | }
33 |
34 | private static BinaryTreeNode GetChildNode(
35 | BinaryTreeNode t, int n)
36 | {
37 | if (n < t.Value)
38 | {
39 | return t.Left;
40 | }
41 | else
42 | {
43 | return t.Right;
44 | }
45 | }
46 | // end::calculateDepth[]
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/BelgianFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | public class BelgianFlag : IFlag
8 | {
9 | public IList Colors
10 | {
11 | get
12 | {
13 | return new List { Color.Black, Color.Red, Color.Yellow };
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/DefaultFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 | public class DefaultFlag : IFlag
7 | {
8 | public IList Colors
9 | {
10 | get
11 | {
12 | return new List { Color.Gray };
13 | }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/DutchFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | // tag::DutchFlag[]
8 | public class DutchFlag : IFlag
9 | {
10 | public IList Colors
11 | {
12 | get
13 | {
14 | return new List { Color.Red, Color.White, Color.Blue };
15 | }
16 | }
17 | }
18 | // end::DutchFlag[]
19 | }
20 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/FlagFactory.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | public class FlagFactory
8 | {
9 |
10 | // tag::getFlag[]
11 | private static readonly Dictionary FLAGS =
12 | new Dictionary();
13 |
14 | static FlagFactory()
15 | {
16 | FLAGS[Nationality.DUTCH] = new DutchFlag();
17 | FLAGS[Nationality.GERMAN] = new GermanFlag();
18 | FLAGS[Nationality.BELGIAN] = new BelgianFlag();
19 | FLAGS[Nationality.FRENCH] = new FrenchFlag();
20 | FLAGS[Nationality.ITALIAN] = new ItalianFlag();
21 | }
22 |
23 | public IList GetFlagColors(Nationality nationality)
24 | {
25 | IFlag flag = FLAGS[nationality];
26 | flag = flag ?? new DefaultFlag();
27 | return flag.Colors;
28 | }
29 | // end::getFlag[]
30 |
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/FrenchFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | public class FrenchFlag : IFlag
8 | {
9 | public IList Colors
10 | {
11 | get
12 | {
13 | return new List { Color.Blue, Color.White, Color.Red };
14 | }
15 | }
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/GermanFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | public class GermanFlag : IFlag
8 | {
9 | public IList Colors
10 | {
11 | get
12 | {
13 | return new List { Color.Black, Color.Red, Color.Yellow };
14 | }
15 | }
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/IFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Collections.Generic;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | // tag::Flag[]
8 | public interface IFlag
9 | {
10 | IList Colors { get; }
11 | }
12 | // end::Flag[]
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch03/withmapandtypes/ItalianFlag.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch03.withmapandtypes
5 | {
6 |
7 | // tag::ItalianFlag[]
8 | public class ItalianFlag : IFlag
9 | {
10 | public IList Colors
11 | {
12 | get
13 | {
14 | return new List { Color.Green, Color.White, Color.Red };
15 | }
16 | }
17 | }
18 | // end::ItalianFlag[]
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/BusinessException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch04
4 | {
5 | [Serializable]
6 | public class BusinessException : Exception
7 | {
8 | public BusinessException(string message) : base(message)
9 | {
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/Clones.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04
2 | {
3 | public class Clones
4 | {
5 | private string givenName;
6 | private string familyName;
7 | private float pageWidthInCm;
8 |
9 | // tag::one-six-line-clone[]
10 | public void SetGivenName(string givenName)
11 | {
12 | this.givenName = givenName;
13 | }
14 |
15 | public void SetFamilyName(string familyName)
16 | {
17 | this.familyName = familyName;
18 | }
19 | // end::one-six-line-clone[]
20 |
21 | public string GetGivenName()
22 | {
23 | return givenName;
24 | }
25 |
26 | public string GetFamilyName()
27 | {
28 | return familyName;
29 | }
30 |
31 | // tag::type-2-clone[]
32 | public void SetPageWidthInInches(float newWidth)
33 | {
34 | float cmPerInch = 2.54f;
35 | this.pageWidthInCm = newWidth * cmPerInch;
36 | // A few more lines.
37 | }
38 |
39 | public void SetPageWidthInPoints(float newWidth)
40 | {
41 | float cmPerPoint = 0.0352777f;
42 | this.pageWidthInCm = newWidth * cmPerPoint;
43 | // A few more lines (same as in setPageWidthInInches).
44 | }
45 | // end::type-2-clone[]
46 |
47 | public float GetPageWidthInCm()
48 | {
49 | return pageWidthInCm;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/Money.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04
2 | {
3 | public class Money
4 | {
5 | public bool GreaterThan(int limit)
6 | {
7 | return true;
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v1/Accounts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch04.v1
4 | {
5 | public static class Accounts
6 | {
7 |
8 | public static CheckingAccount FindAcctByNumber(string number)
9 | {
10 | return new CheckingAccount();
11 | }
12 |
13 | // tag::isValid[]
14 | public static bool IsValid(string number)
15 | {
16 | int sum = 0;
17 | for (int i = 0; i < number.Length; i++)
18 | {
19 | sum = sum + (9 - i) * (int)Char.GetNumericValue(number[i]);
20 | }
21 | return sum % 11 == 0;
22 | }
23 | // end::isValid[]
24 | }
25 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v1/CheckingAccount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | namespace eu.sig.training.ch04.v1
3 | {
4 | // tag::CheckingAccount[]
5 | public class CheckingAccount
6 | {
7 | private int transferLimit = 100;
8 |
9 | public Transfer MakeTransfer(String counterAccount, Money amount)
10 | {
11 | // 1. Check withdrawal limit:
12 | if (amount.GreaterThan(this.transferLimit))
13 | {
14 | throw new BusinessException("Limit exceeded!");
15 | }
16 | // 2. Assuming result is 9-digit bank account number, validate 11-test:
17 | int sum = 0;
18 | for (int i = 0; i < counterAccount.Length; i++)
19 | {
20 | sum = sum + (9 - i) * (int)Char.GetNumericValue(
21 | counterAccount[i]);
22 | }
23 | if (sum % 11 == 0)
24 | {
25 | // 3. Look up counter account and make transfer object:
26 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
27 | Transfer result = new Transfer(this, acct, amount);
28 | return result;
29 | }
30 | else
31 | {
32 | throw new BusinessException("Invalid account number!");
33 | }
34 | }
35 | }
36 | // end::CheckingAccount[]
37 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v1/SavingsAccount.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch04.v1
4 | {
5 | // tag::SavingsAccount[]
6 | public class SavingsAccount
7 | {
8 | public CheckingAccount RegisteredCounterAccount { get; set; }
9 |
10 | public Transfer makeTransfer(string counterAccount, Money amount)
11 | {
12 | // 1. Assuming result is 9-digit bank account number, validate 11-test:
13 | int sum = 0; // <1>
14 | for (int i = 0; i < counterAccount.Length; i++)
15 | {
16 | sum = sum + (9 - i) * (int)Char.GetNumericValue(
17 | counterAccount[i]);
18 | }
19 | if (sum % 11 == 0)
20 | {
21 | // 2. Look up counter account and make transfer object:
22 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
23 | Transfer result = new Transfer(this, acct, amount); // <2>
24 | // 3. Check whether withdrawal is to registered counter account:
25 | if (result.CounterAccount.Equals(this.RegisteredCounterAccount))
26 | {
27 | return result;
28 | }
29 | else
30 | {
31 | throw new BusinessException("Counter-account not registered!");
32 | }
33 | }
34 | else
35 | {
36 | throw new BusinessException("Invalid account number!!");
37 | }
38 | }
39 | }
40 | // end::SavingsAccount[]
41 | }
42 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v1/Transfer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v1
2 | {
3 |
4 | public class Transfer
5 | {
6 | public CheckingAccount CounterAccount { get; set; }
7 |
8 | public Transfer(CheckingAccount acct1, CheckingAccount acct2, Money m)
9 | {
10 | }
11 |
12 | public Transfer(SavingsAccount acct1, CheckingAccount acct2, Money m)
13 | {
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v2/Accounts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch04.v2
4 | {
5 |
6 | public static class Accounts
7 | {
8 |
9 | public static CheckingAccount FindAcctByNumber(string number)
10 | {
11 | return new CheckingAccount();
12 | }
13 |
14 | // tag::isValid[]
15 | public static bool IsValid(string number)
16 | {
17 | int sum = 0;
18 | for (int i = 0; i < number.Length; i++)
19 | {
20 | sum = sum + (9 - i) * (int)Char.GetNumericValue(number[i]);
21 | }
22 | return sum % 11 == 0;
23 | }
24 | // end::isValid[]
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v2/CheckingAccount.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v2
2 | {
3 |
4 | // tag::CheckingAccount[]
5 | public class CheckingAccount
6 | {
7 | private int transferLimit = 100;
8 |
9 | public Transfer MakeTransfer(string counterAccount, Money amount)
10 | {
11 | // 1. Check withdrawal limit:
12 | if (amount.GreaterThan(this.transferLimit))
13 | {
14 | throw new BusinessException("Limit exceeded!");
15 | }
16 | if (Accounts.IsValid(counterAccount))
17 | { // <1>
18 | // 2. Look up counter account and make transfer object:
19 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
20 | Transfer result = new Transfer(this, acct, amount); // <2>
21 | return result;
22 | }
23 | else
24 | {
25 | throw new BusinessException("Invalid account number!");
26 | }
27 | }
28 | }
29 | // end::CheckingAccount[]
30 | }
31 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v2/SavingsAccount.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v2
2 | {
3 |
4 | // tag::SavingsAccount[]
5 | public class SavingsAccount
6 | {
7 | public CheckingAccount RegisteredCounterAccount { get; set; }
8 |
9 | public Transfer MakeTransfer(string counterAccount, Money amount)
10 | {
11 | // 1. Assuming result is 9-digit bank account number, validate 11-test:
12 | if (Accounts.IsValid(counterAccount))
13 | { // <1>
14 | // 2. Look up counter account and make transfer object:
15 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
16 | Transfer result = new Transfer(this, acct, amount); // <2>
17 | if (result.CounterAccount.Equals(this.RegisteredCounterAccount))
18 | {
19 | return result;
20 | }
21 | else
22 | {
23 | throw new BusinessException("Counter-account not registered!");
24 | }
25 | }
26 | else
27 | {
28 | throw new BusinessException("Invalid account number!!");
29 | }
30 | }
31 | }
32 | // end::SavingsAccount[]
33 | }
34 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v2/Transfer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v2
2 | {
3 |
4 | public class Transfer
5 | {
6 | public CheckingAccount CounterAccount { get; set; }
7 |
8 | public Transfer(CheckingAccount acct1, CheckingAccount acct2, Money m)
9 | {
10 | }
11 |
12 | public Transfer(SavingsAccount acct1, CheckingAccount acct2, Money m)
13 | {
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v3/Account.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch04.v3
4 | {
5 |
6 | // tag::Account[]
7 | public class Account
8 | {
9 | public virtual Transfer MakeTransfer(string counterAccount, Money amount)
10 | {
11 | // 1. Assuming result is 9-digit bank account number, validate 11-test:
12 | int sum = 0; // <1>
13 | for (int i = 0; i < counterAccount.Length; i++)
14 | {
15 | sum = sum + (9 - i) * (int)Char.
16 | GetNumericValue(counterAccount[i]);
17 | }
18 | if (sum % 11 == 0)
19 | {
20 | // 2. Look up counter account and make transfer object:
21 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
22 | Transfer result = new Transfer(this, acct, amount); // <2>
23 | return result;
24 | }
25 | else
26 | {
27 | throw new BusinessException("Invalid account number!");
28 | }
29 | }
30 | }
31 | // end::Account[]
32 |
33 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v3/Accounts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace eu.sig.training.ch04.v3
5 | {
6 |
7 | public static class Accounts
8 | {
9 |
10 | // The Java version of the Account class does not have a string Number as property,
11 | // and the Java edition of the book is already in print. So we add an external
12 | // association of Accounts and their numbers.
13 | public static Dictionary ACCOUNTS = new Dictionary();
14 | public static Dictionary NUMBERS = new Dictionary();
15 |
16 | public static CheckingAccount FindAcctByNumber(string number)
17 | {
18 | var myAccount = ACCOUNTS[number];
19 | if (myAccount is CheckingAccount)
20 | {
21 | return (CheckingAccount)myAccount;
22 | }
23 | else
24 | {
25 | throw new BusinessException("Not a checking account.");
26 | }
27 | }
28 |
29 | public static T MakeAccount(string number) where T : Account, new()
30 | {
31 | var myAccount = new T();
32 | ACCOUNTS[number] = myAccount;
33 | NUMBERS[myAccount] = number;
34 | return myAccount;
35 | }
36 |
37 | public static string GetAccountNumber(Account acct)
38 | {
39 | return NUMBERS[acct];
40 | }
41 |
42 | // tag::isValid[]
43 | public static bool IsValid(string number)
44 | {
45 | int sum = 0;
46 | for (int i = 0; i < number.Length; i++)
47 | {
48 | sum = sum + (9 - i) * (int)Char.GetNumericValue(number[i]);
49 | }
50 | return sum % 11 == 0;
51 | }
52 | // end::isValid[]
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v3/CheckingAccount.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v3
2 | {
3 |
4 | // tag::CheckingAccount[]
5 | public class CheckingAccount : Account
6 | {
7 | private int transferLimit = 100;
8 |
9 | public override Transfer MakeTransfer(string counterAccount, Money amount)
10 | {
11 | if (amount.GreaterThan(this.transferLimit))
12 | {
13 | throw new BusinessException("Limit exceeded!");
14 | }
15 | return base.MakeTransfer(counterAccount, amount);
16 | }
17 | }
18 | // end::CheckingAccount[]
19 |
20 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v3/SavingsAccount.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v3
2 | {
3 |
4 | // tag::SavingsAccount[]
5 | public class SavingsAccount : Account
6 | {
7 | public CheckingAccount RegisteredCounterAccount { get; set; }
8 |
9 | public override Transfer MakeTransfer(string counterAccount, Money amount)
10 | {
11 | Transfer result = base.MakeTransfer(counterAccount, amount);
12 | if (result.CounterAccount.Equals(this.RegisteredCounterAccount))
13 | {
14 | return result;
15 | }
16 | else
17 | {
18 | throw new BusinessException("Counter-account not registered!");
19 | }
20 | }
21 | }
22 | // end::SavingsAccount[]
23 |
24 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v3/Transfer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch04.v3
2 | {
3 |
4 | public class Transfer
5 | {
6 | public CheckingAccount CounterAccount { get; set; }
7 |
8 | public Transfer(Account acct1, CheckingAccount acct2, Money m)
9 | {
10 | CounterAccount = acct2;
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v4/Account.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using eu.sig.training.ch04.v3;
3 |
4 | namespace eu.sig.training.ch04.v4
5 | {
6 |
7 | // tag::Account[]
8 | public class Account
9 | {
10 | public Transfer MakeTransfer(string counterAccount, Money amount)
11 | {
12 | if (IsValid(counterAccount))
13 | {
14 | CheckingAccount acct = Accounts.FindAcctByNumber(counterAccount);
15 | return new Transfer(this, acct, amount);
16 | }
17 | else
18 | {
19 | throw new BusinessException("Invalid account number!");
20 | }
21 | }
22 |
23 | public static bool IsValid(string number)
24 | {
25 | int sum = 0;
26 | for (int i = 0; i < number.Length; i++)
27 | {
28 | sum = sum + (9 - i) * (int)Char.GetNumericValue(number[i]);
29 | }
30 | return sum % 11 == 0;
31 | }
32 | }
33 | // end::Account[]
34 |
35 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v4/Accounts.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using eu.sig.training.ch04.v3;
3 |
4 | namespace eu.sig.training.ch04.v4
5 | {
6 |
7 | public static class Accounts
8 | {
9 | public static CheckingAccount FindAcctByNumber(string number)
10 | {
11 | return new CheckingAccount();
12 | }
13 |
14 | // Version that should make tests succeed (not used in book):
15 | public static bool IsValid(string number)
16 | {
17 | if (number.Length != 9)
18 | {
19 | return false;
20 | }
21 | int sum = 0;
22 | for (int i = 0; i < number.Length; i++)
23 | {
24 | if (!Char.IsDigit(number[i]))
25 | {
26 | return false;
27 | }
28 | sum = sum + (9 - i) * (int)Char.GetNumericValue(number[i]);
29 | }
30 | return sum % 11 == 0;
31 | }
32 |
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch04/v4/Transfer.cs:
--------------------------------------------------------------------------------
1 | using eu.sig.training.ch04.v3;
2 |
3 | namespace eu.sig.training.ch04.v4
4 | {
5 |
6 | public class Transfer
7 | {
8 | public CheckingAccount CounterAccount { get; set; }
9 |
10 | public Transfer(Account acct1, CheckingAccount acct2, Money m)
11 | {
12 | }
13 | }
14 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/boardpanel/v1/BoardPanel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch05.boardpanel.v1
5 | {
6 | public class BoardPanel
7 | {
8 | // tag::render[]
9 | ///
10 | /// Renders a single square on the given graphics context on the specified
11 | /// rectangle.
12 | ///
13 | /// The square to render.
14 | /// The graphics context to draw on.
15 | /// The x position to start drawing.
16 | /// The y position to start drawing.
17 | /// The width of this square (in pixels.)
18 | /// The height of this square (in pixels.)
19 | private void Render(Square square, Graphics g, int x, int y, int w, int h)
20 | {
21 | square.Sprite.Draw(g, x, y, w, h);
22 | foreach (Unit unit in square.Occupants)
23 | {
24 | unit.Sprite.Draw(g, x, y, w, h);
25 | }
26 | }
27 | // end::render[]
28 |
29 | private class Sprite
30 | {
31 | public void Draw(Graphics g, int x, int y, int w, int h)
32 | {
33 |
34 | }
35 | }
36 |
37 | private class Unit
38 | {
39 | public Sprite Sprite { get; set; }
40 | }
41 |
42 | private class Square : Unit
43 | {
44 |
45 | public IList Occupants { get; set; }
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/boardpanel/v2/BoardPanel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 |
4 | namespace eu.sig.training.ch05.boardpanel.v2
5 | {
6 |
7 | public class BoardPanel
8 | {
9 | // tag::render[]
10 | ///
11 | /// Renders a single square on the given graphics context on the specified
12 | /// rectangle.
13 | ///
14 | /// The square to render.
15 | /// The graphics context to draw on.
16 | /// The position and dimension for rendering the square.
17 | private void Render(Square square, Graphics g, Rectangle r)
18 | {
19 | Point position = r.Position;
20 | square.Sprite.Draw(g, position.X, position.Y, r.Width, r.Height);
21 | foreach (Unit unit in square.Occupants)
22 | {
23 | unit.Sprite.Draw(g, position.X, position.Y, r.Width, r.Height);
24 | }
25 | }
26 | // end::render[]
27 |
28 | private class Sprite
29 | {
30 | public void Draw(Graphics g, int x, int y, int w, int h)
31 | {
32 |
33 | }
34 | }
35 |
36 | private class Unit
37 | {
38 | public Sprite Sprite { get; set; }
39 | }
40 |
41 | private class Square : Unit
42 | {
43 |
44 | public IList Occupants { get; set; }
45 |
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/boardpanel/v2/Rectangle.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch05.boardpanel.v2
4 | {
5 | // tag::Rectangle[]
6 | public class Rectangle
7 | {
8 | public Point Position { get; set; }
9 |
10 | public int Width { get; set; }
11 |
12 | public int Height { get; set; }
13 |
14 | public Rectangle(Point position, int width, int height)
15 | {
16 | this.Position = position;
17 | this.Width = width;
18 | this.Height = height;
19 | }
20 |
21 | }
22 | // end::Rectangle[]
23 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/boardpanel/v3/BoardPanel.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using Rectangle = eu.sig.training.ch05.boardpanel.v2.Rectangle;
4 |
5 | namespace eu.sig.training.ch05.boardpanel.v3
6 | {
7 |
8 | public class BoardPanel
9 | {
10 | ///
11 | /// Renders a single square on the given graphics context on the specified
12 | /// rectangle.
13 | ///
14 | /// The square to render.
15 | /// The graphics context to draw on.
16 | /// The position and dimension for rendering the square.
17 | // tag::render[]
18 | private void Render(Square square, Graphics g, Rectangle r)
19 | {
20 | Point position = r.Position;
21 | square.Sprite.Draw(g, r);
22 | foreach (Unit unit in square.Occupants)
23 | {
24 | unit.Sprite.Draw(g, r);
25 | }
26 | }
27 | // end::render[]
28 |
29 | private class Sprite
30 | {
31 | public void Draw(Graphics g, Rectangle r)
32 | {
33 |
34 | }
35 | }
36 |
37 | private class Unit
38 | {
39 | public Sprite Sprite { get; set; }
40 | }
41 |
42 | private class Square : Unit
43 | {
44 |
45 | public IList Occupants { get; set; }
46 |
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/buildandsendmail/v1/BuildAndSendMail.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch05.buildandsendmail.v1
2 | {
3 | public class BuildAndSendMail
4 | {
5 | // tag::buildAndSendMail[]
6 | public void DoBuildAndSendMail(MailMan m, string firstName, string lastName,
7 | string division, string subject, MailFont font, string message1,
8 | string message2, string message3)
9 | {
10 | // Format the email address
11 | string mId = $"{firstName[0]}.{lastName.Substring(0, 7)}" +
12 | $"@{division.Substring(0, 5)}.compa.ny";
13 | // Format the message given the content type and raw message
14 | MailMessage mMessage = FormatMessage(font,
15 | message1 + message2 + message3);
16 | // Send message
17 | m.Send(mId, subject, mMessage);
18 | }
19 | // end::buildAndSendMail[]
20 |
21 | public MailMessage FormatMessage(MailFont font, string s)
22 | {
23 | return null;
24 | }
25 |
26 | public class MailMan
27 | {
28 |
29 | public void Send(string mId, string subject, MailMessage mMessage) { }
30 |
31 | }
32 |
33 | public class MailFont
34 | {
35 |
36 | }
37 |
38 | public class MailMessage
39 | {
40 |
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/buildandsendmail/v2/BuildAndSendMail.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace eu.sig.training.ch05.buildandsendmail.v2
3 | {
4 | public class BuildAndSendMail
5 | {
6 |
7 | // tag::buildAndSendMail[]
8 | public void DoBuildAndSendMail(MailMan m, MailAddress mAddress,
9 | MailBody mBody)
10 | {
11 | // Build the mail
12 | Mail mail = new Mail(mAddress, mBody);
13 | // Send the mail
14 | m.SendMail(mail);
15 | }
16 |
17 | public class Mail
18 | {
19 | public MailAddress Address { get; set; }
20 | public MailBody Body { get; set; }
21 |
22 | public Mail(MailAddress mAddress, MailBody mBody)
23 | {
24 | this.Address = mAddress;
25 | this.Body = mBody;
26 | }
27 | }
28 |
29 | public class MailBody
30 | {
31 | public string Subject { get; set; }
32 | public MailMessage Message { get; set; }
33 |
34 | public MailBody(string subject, MailMessage message)
35 | {
36 | this.Subject = subject;
37 | this.Message = message;
38 | }
39 | }
40 |
41 | public class MailAddress
42 | {
43 | public string MsgId { get; private set; }
44 |
45 | public MailAddress(string firstName, string lastName,
46 | string division)
47 | {
48 | this.MsgId = $"{firstName[0]}.{lastName.Substring(0, 7)}" +
49 | $"@{division.Substring(0, 5)}.compa.ny";
50 | }
51 | }
52 | // end::buildAndSendMail[]
53 |
54 | public MailMessage FormatMessage(MailFont font, string s)
55 | {
56 | return null;
57 | }
58 |
59 | public class MailMan
60 | {
61 | public void Send(string mId, string subject, MailMessage mMessage) { }
62 | public void SendMail(Mail mail) { }
63 | }
64 |
65 | public class MailFont { }
66 |
67 | public class MailMessage { }
68 |
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch05/chartlib/v1/Charts.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using Rectangle = eu.sig.training.ch05.boardpanel.v2.Rectangle;
3 |
4 | namespace eu.sig.training.ch05.chartlib.v1
5 | {
6 | public class Charts
7 | {
8 | // tag::drawBarChart[]
9 | public static void DrawBarChart(Graphics g,
10 | CategoryItemRendererState state,
11 | Rectangle graphArea,
12 | CategoryPlot plot,
13 | CategoryAxis domainAxis,
14 | ValueAxis rangeAxis,
15 | CategoryDataset dataset)
16 | {
17 | // ..
18 | }
19 | // end::drawBarChart[]
20 |
21 | // tag::drawBarChartDefault[]
22 | public static void DrawBarChart(Graphics g, CategoryDataset dataset)
23 | {
24 | Charts.DrawBarChart(g,
25 | CategoryItemRendererState.DEFAULT,
26 | new Rectangle(new Point(0, 0), 100, 100),
27 | CategoryPlot.DEFAULT,
28 | CategoryAxis.DEFAULT,
29 | ValueAxis.DEFAULT,
30 | dataset);
31 | }
32 | // end::drawBarChartDefault[]
33 | }
34 |
35 | public class CategoryItemRendererState
36 | {
37 | public const CategoryItemRendererState DEFAULT = null;
38 | }
39 |
40 | public class CategoryPlot
41 | {
42 | public const CategoryPlot DEFAULT = null;
43 | }
44 |
45 | public class CategoryAxis
46 | {
47 | public const CategoryAxis DEFAULT = null;
48 | }
49 |
50 | public class ValueAxis
51 | {
52 | public const ValueAxis DEFAULT = null;
53 | }
54 |
55 | public class CategoryDataset
56 | {
57 | public const CategoryDataset DEFAULT = null;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/advanceddigitalcamera/DigitalCamera.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.advanceddigitalcamera
4 | {
5 |
6 | // tag::DigitalCamera[]
7 | public class DigitalCamera
8 | {
9 | public Image TakeSnapshot()
10 | {
11 | // ...
12 | // end::DigitalCamera[]
13 | return Image.FromFile("");
14 | // tag::DigitalCamera[]
15 | }
16 |
17 | public void FlashLightOn()
18 | {
19 | // ...
20 | }
21 |
22 | public void FlaslLightOff()
23 | {
24 | // ...
25 | }
26 |
27 | public Image TakePanoramaSnapshot()
28 | {
29 | // end::DigitalCamera[]
30 | return Image.FromFile("");
31 | // tag::DigitalCamera[]
32 | // ...
33 | }
34 |
35 | public Video Record()
36 | {
37 | // ...
38 | // end::DigitalCamera[]
39 | return new Video();
40 | // tag::DigitalCamera[]
41 | }
42 |
43 | public void SetTimer(int seconds)
44 | {
45 | // ...
46 | }
47 |
48 | public void ZoomIn()
49 | {
50 | // ...
51 | }
52 |
53 | public void ZoomOut()
54 | {
55 | // ...
56 | }
57 | }
58 | // end::DigitalCamera[]
59 | }
60 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/advanceddigitalcamera/Video.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.advanceddigitalcamera
2 | {
3 |
4 | public class Video
5 | {
6 | }
7 |
8 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/digitalcamera/DigitalCamera.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.digitalcamera
4 | {
5 |
6 | // tag::DigitalCamera[]
7 | public class DigitalCamera
8 | {
9 | public Image TakeSnapshot()
10 | {
11 | // ...
12 | // end::DigitalCamera[]
13 | return Image.FromFile("");
14 | // tag::DigitalCamera[]
15 | }
16 |
17 | public void FlashLightOn()
18 | {
19 | // ...
20 | }
21 |
22 | public void FlashLightOff()
23 | {
24 | // ...
25 | }
26 | }
27 | // end::DigitalCamera[]
28 | }
29 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/digitalcamera/SmartphoneApp.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.digitalcamera
4 | {
5 |
6 | #pragma warning disable 219
7 | // tag::SmartphoneApp[]
8 | public class SmartphoneApp
9 | {
10 | private static DigitalCamera camera = new DigitalCamera();
11 |
12 | public static void Main(string[] args)
13 | {
14 | // ...
15 | Image image = camera.TakeSnapshot();
16 | // ...
17 | }
18 | }
19 | // end::SmartphoneApp[]
20 | #pragma warning restore 219
21 | }
22 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/simpledigitalcamera/DigitalCamera.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.simpledigitalcamera
4 | {
5 |
6 | // tag::DigitalCamera[]
7 | public class DigitalCamera : ISimpleDigitalCamera
8 | {
9 | // ...
10 | // end::DigitalCamera[]
11 | public Image TakeSnapshot()
12 | {
13 | return null;
14 | }
15 |
16 | public void FlashLightOn()
17 | {
18 | }
19 |
20 | public void FlashLightOff()
21 | {
22 | }
23 | // tag::DigitalCamera[]
24 | }
25 | // end::DigitalCamera[]
26 | }
27 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/simpledigitalcamera/ISimpleDigitalCamera.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.simpledigitalcamera
4 | {
5 |
6 | // tag::SimpleDigitalCamera[]
7 | public interface ISimpleDigitalCamera
8 | {
9 | Image TakeSnapshot();
10 |
11 | void FlashLightOn();
12 |
13 | void FlashLightOff();
14 | }
15 | // end::SimpleDigitalCamera[]
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/simpledigitalcamera/SDK.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.simpledigitalcamera
2 | {
3 |
4 | public class SDK
5 | {
6 | public static ISimpleDigitalCamera GetCamera()
7 | {
8 | return new DigitalCamera();
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/simpledigitalcamera/SmartphoneApp.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 |
3 | namespace eu.sig.training.ch06.simpledigitalcamera
4 | {
5 |
6 | #pragma warning disable 219
7 | // tag::SmartphoneApp[]
8 | public class SmartphoneApp
9 | {
10 | private static ISimpleDigitalCamera camera = SDK.GetCamera();
11 |
12 | public static void Main(string[] args)
13 | {
14 | // ...
15 | Image image = camera.TakeSnapshot();
16 | // ...
17 | }
18 | }
19 | // end::SmartphoneApp[]
20 | #pragma warning restore 219
21 | }
22 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/NotificationType.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice
2 | {
3 |
4 | public class NotificationType
5 | {
6 | public static NotificationType FromString(string type)
7 | {
8 | return new NotificationType();
9 | }
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/User.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice
2 | {
3 |
4 | public class User
5 | {
6 | public string Name { get; set; }
7 |
8 | public User()
9 | {
10 | Name = "user@example.com";
11 | }
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/UserInfo.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice
2 | {
3 |
4 | public class UserInfo
5 | {
6 | }
7 |
8 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/splitted/UserBlockService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch06.userservice.splitted
4 | {
5 |
6 | // tag::UserBlockService[]
7 | public class UserBlockService
8 | {
9 | public void BlockUser(User user)
10 | {
11 | // ...
12 | }
13 |
14 | public IList GetAllBlockedUsers()
15 | {
16 | // ...
17 | // end::UserBlockService[]
18 | return new List();
19 | // tag::UserBlockService[]
20 | }
21 | }
22 | // end::UserBlockService[]
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/splitted/UserNotificationService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch06.userservice.splitted
4 | {
5 |
6 | // tag::UserNotificationService[]
7 | public class UserNotificationService
8 | {
9 | public IList GetNotificationTypes(User user)
10 | {
11 | // ...
12 | // end::UserNotificationService[]
13 | return new List();
14 | // tag::UserNotificationService[]
15 | }
16 |
17 | public void Register(User user, NotificationType type)
18 | {
19 | // ...
20 | }
21 |
22 | public void Unregister(User user, NotificationType type)
23 | {
24 | // ...
25 | }
26 | }
27 | // end::UserNotificationService[]
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/splitted/UserService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch06.userservice.splitted
4 | {
5 |
6 | // tag::UserService[]
7 | public class UserService
8 | {
9 | public User LoadUser(string userId)
10 | {
11 | // ...
12 | // end::UserService[]
13 | return new User();
14 | // tag::UserService[]
15 | }
16 |
17 | public bool DoesUserExist(string userId)
18 | {
19 | // ...
20 | // end::UserService[]
21 | return true;
22 | // tag::UserService[]
23 | }
24 |
25 | public User ChangeUserInfo(UserInfo userInfo)
26 | {
27 | // ...
28 | // end::UserService[]
29 | return new User();
30 | // tag::UserService[]
31 | }
32 |
33 | public IList SearchUsers(UserInfo userInfo)
34 | {
35 | // ...
36 | // end::UserService[]
37 | return new List();
38 | // tag::UserService[]
39 | }
40 | }
41 | // end::UserService[]
42 | }
43 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/v1/UserRestAPI.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice.v1
2 | {
3 |
4 | // tag::UserRestAPI[]
5 | public class UserController : System.Web.Http.ApiController
6 | {
7 |
8 | private readonly UserService userService = new UserService();
9 |
10 | // ...
11 |
12 | public System.Web.Http.IHttpActionResult GetUserById(string id)
13 | {
14 | User user = userService.LoadUser(id);
15 | if (user == null)
16 | {
17 | return NotFound();
18 | }
19 | return Ok(user);
20 | }
21 | }
22 | // end::UserRestAPI[]
23 | }
24 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/v1/UserService.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice.v1
2 | {
3 |
4 | // tag::UserService[]
5 | public class UserService
6 | {
7 | public User LoadUser(string userId)
8 | {
9 | // ...
10 | // end::UserService[]
11 | return new User();
12 | // tag::UserService[]
13 | }
14 |
15 | public bool DoesUserExist(string userId)
16 | {
17 | // ...
18 | // end::UserService[]
19 | return true;
20 | // tag::UserService[]
21 | }
22 |
23 | public User ChangeUserInfo(UserInfo userInfo)
24 | {
25 | // ...
26 | // end::UserService[]
27 | return new User();
28 | // tag::UserService[]
29 | }
30 | }
31 | // end::UserSerice[]
32 | }
33 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/v2/NotificationRestAPI.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch06.userservice.v2
2 | {
3 |
4 | // tag::NotificationRestAPI[]
5 | public class NotificationController : System.Web.Http.ApiController
6 | {
7 | private readonly UserService userService = new UserService();
8 |
9 | // ...
10 |
11 | public System.Web.Http.IHttpActionResult Register(string id,
12 | string notificationType)
13 | {
14 | User user = userService.LoadUser(id);
15 | userService.RegisterForNotifications(user,
16 | NotificationType.FromString(notificationType));
17 | return Ok();
18 | }
19 |
20 | [System.Web.Http.HttpPost]
21 | [System.Web.Http.ActionName("unregister")]
22 | public System.Web.Http.IHttpActionResult Unregister(string id,
23 | string notificationType)
24 | {
25 | User user = userService.LoadUser(id);
26 | userService.UnregisterForNotifications(user,
27 | NotificationType.FromString(notificationType));
28 | return Ok();
29 | }
30 | }
31 | // end::NotificationRestAPI[]
32 | }
33 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/v2/UserService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch06.userservice.v2
4 | {
5 |
6 | // tag::UserService[]
7 | public class UserService
8 | {
9 | public User LoadUser(string userId)
10 | {
11 | // ...
12 | // end::UserService[]
13 | return new User();
14 | // tag::UserService[]
15 | }
16 |
17 | public bool DoesUserExist(string userId)
18 | {
19 | // ...
20 | // end::UserService[]
21 | return true;
22 | // tag::UserService[]
23 | }
24 |
25 | public User ChangeUserInfo(UserInfo userInfo)
26 | {
27 | // ...
28 | // end::UserService[]
29 | return new User();
30 | // tag::UserService[]
31 | }
32 |
33 | public List GetNotificationTypes(User user)
34 | {
35 | // ...
36 | // end::UserService[]
37 | return new List();
38 | // tag::UserService[]
39 | }
40 |
41 | public void RegisterForNotifications(User user, NotificationType type)
42 | {
43 | // ...
44 | }
45 |
46 | public void UnregisterForNotifications(User user, NotificationType type)
47 | {
48 | // ...
49 | }
50 | }
51 | // end::UserSerice[]
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch06/userservice/v3/UserService.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace eu.sig.training.ch06.userservice.v3
4 | {
5 |
6 | // tag::UserService[]
7 | public class UserService
8 | {
9 | public User LoadUser(string userId)
10 | {
11 | // ...
12 | // end::UserService[]
13 | return new User();
14 | // tag::UserService[]
15 | }
16 |
17 | public bool DoesUserExist(string userId)
18 | {
19 | // ...
20 | // end::UserService[]
21 | return true;
22 | // tag::UserService[]
23 | }
24 |
25 | public User ChangeUserInfo(UserInfo userInfo)
26 | {
27 | // ...
28 | // end::UserService[]
29 | return new User();
30 | // tag::UserService[]
31 | }
32 |
33 | public List GetNotificationTypes(User user)
34 | {
35 | // ...
36 | // end::UserService[]
37 | return new List();
38 | // tag::UserService[]
39 | }
40 |
41 | public void RegisterForNotifications(User user, NotificationType type)
42 | {
43 | // ...
44 | }
45 |
46 | public void UnregisterForNotifications(User user, NotificationType type)
47 | {
48 | // ...
49 | }
50 |
51 | public List SearchUsers(UserInfo userInfo)
52 | {
53 | // ...
54 | // end::UserService[]
55 | return new List();
56 | // tag::UserService[]
57 | }
58 |
59 | public void BlockUser(User user)
60 | {
61 | // ...
62 | }
63 |
64 | public List GetAllBlockedUsers()
65 | {
66 | // ...
67 | // end::UserService[]
68 | return new List();
69 | // tag::UserService[]
70 | }
71 | }
72 | // end::UserSerice[]
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AWSCloudServerFactory.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | // tag::AWSCloudServerFactory[]
4 | public class AWSCloudServerFactory : ICloudServerFactory
5 | {
6 | public ICloudServer LaunchComputeServer()
7 | {
8 | return new AWSComputeServer();
9 | }
10 |
11 | public ICloudServer LaunchDatabaseServer()
12 | {
13 | return new AWSDatabaseServer();
14 | }
15 |
16 | public ICloudStorage CreateCloudStorage(long sizeGb)
17 | {
18 | return new AWSCloudStorage(sizeGb);
19 | }
20 | }
21 | // end::AWSCloudServerFactory[]
22 | }
23 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AWSCloudStorage.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AWSCloudStorage : ICloudStorage
4 | {
5 | public AWSCloudStorage(long sizeGb)
6 | {
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AWSComputeServer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AWSComputeServer : ICloudServer
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AWSDatabaseServer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AWSDatabaseServer : ICloudServer
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/ApplicationLauncher.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | // tag::ApplicationLauncher[]
4 | public class ApplicationLauncher
5 | {
6 |
7 | public static void Main(string[] args)
8 | {
9 | ICloudServerFactory factory;
10 | if (args[1].Equals("-azure"))
11 | {
12 | factory = new AzureCloudServerFactory();
13 | }
14 | else
15 | {
16 | factory = new AWSCloudServerFactory();
17 | }
18 | ICloudServer computeServer = factory.LaunchComputeServer();
19 | ICloudServer databaseServer = factory.LaunchDatabaseServer();
20 | // end::ApplicationLauncher[]
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AzureCloudServerFactory.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07 {
2 | // tag::AzureCloudServerFactory[]
3 | public class AzureCloudServerFactory : ICloudServerFactory {
4 | public ICloudServer LaunchComputeServer() {
5 | return new AzureComputeServer();
6 | }
7 |
8 | public ICloudServer LaunchDatabaseServer() {
9 | return new AzureDatabaseServer();
10 | }
11 |
12 | public ICloudStorage CreateCloudStorage(long sizeGb) {
13 | return new AzureCloudStorage(sizeGb);
14 | }
15 | }
16 | // end::AzureCloudServerFactory[]
17 | }
18 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AzureCloudStorage.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AzureCloudStorage : ICloudStorage
4 | {
5 | public AzureCloudStorage(long sizeGb)
6 | {
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AzureComputeServer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AzureComputeServer : ICloudServer
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/AzureDatabaseServer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public class AzureDatabaseServer : ICloudServer
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/ICloudServer.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public interface ICloudServer
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/ICloudServerFactory.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | // tag::CloudServerFactory[]
4 | public interface ICloudServerFactory
5 | {
6 | ICloudServer LaunchComputeServer();
7 |
8 | ICloudServer LaunchDatabaseServer();
9 |
10 | ICloudStorage CreateCloudStorage(long sizeGb);
11 | }
12 | // end::CloudServerFactory[]
13 | }
14 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch07/ICloudStorage.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch07
2 | {
3 | public interface ICloudStorage
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch10/PerfectPicture.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using eu.sig.training.ch06.simpledigitalcamera;
3 |
4 | namespace eu.sig.training.ch10
5 | {
6 | public class PerfectPicture
7 | {
8 | public static ISimpleDigitalCamera camera = null;
9 |
10 | // tag::takePerfectPicture[]
11 | public const int DAYLIGHT_START = 6;
12 |
13 | public Image TakePerfectPicture(int currentHour)
14 | {
15 | Image image;
16 | if (currentHour < PerfectPicture.DAYLIGHT_START)
17 | {
18 | camera.FlashLightOn();
19 | image = camera.TakeSnapshot();
20 | camera.FlashLightOff();
21 | }
22 | else
23 | {
24 | image = camera.TakeSnapshot();
25 | }
26 | return image;
27 | }
28 | // end::takePerfectPicture[]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch10/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using eu.sig.training.ch04.v1;
3 |
4 | namespace eu.sig.training.ch10
5 | {
6 | public class Program
7 | {
8 | [STAThread]
9 | public static void Main(string[] args)
10 | {
11 | string acct;
12 | do
13 | {
14 | Console.WriteLine("Type a bank account number on the next line.");
15 | acct = Console.ReadLine();
16 | Console.WriteLine($"Bank account number '{acct}' is" +
17 | (Accounts.IsValid(acct) ? "" : " not") + " valid.");
18 | } while (!String.IsNullOrEmpty(acct));
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch11/DeadCode.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch11
2 | {
3 |
4 | public class DeadCode
5 | {
6 | public class Transaction
7 | {
8 | public Transaction(long uid)
9 | {
10 | }
11 | }
12 |
13 | // tag::getTransaction[]
14 | public Transaction GetTransaction(long uid)
15 | {
16 | Transaction result = new Transaction(uid);
17 | if (result != null)
18 | {
19 | return result;
20 | }
21 | else
22 | {
23 | return LookupTransaction(uid); // <1>
24 | }
25 | }
26 | // end::getTransaction[]
27 |
28 | private Transaction LookupTransaction(long uid)
29 | {
30 | return null;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch11/MagicConstants.cs:
--------------------------------------------------------------------------------
1 | namespace eu.sig.training.ch11
2 | {
3 | public class MagicConstants
4 | {
5 |
6 | public class Customer
7 | {
8 |
9 | public Customer(int age)
10 | {
11 | this.Age = age;
12 | }
13 |
14 | public int Age { get; set; }
15 | }
16 |
17 | public class UseMagicConstants
18 | {
19 |
20 | // tag::calculateFareMagicConstants[]
21 | float CalculateFare(Customer c, long distance)
22 | {
23 | float travelledDistanceFare = distance * 0.10f;
24 | if (c.Age < 12)
25 | {
26 | travelledDistanceFare *= 0.25f;
27 | }
28 | else
29 | if (c.Age >= 65)
30 | {
31 | travelledDistanceFare *= 0.5f;
32 | }
33 | return 3.00f + travelledDistanceFare;
34 | }
35 | // end::calculateFareMagicConstants[]
36 |
37 | }
38 |
39 | public class DoNotUseMagicConstants
40 | {
41 | // tag::calculateFareDoNotUseMagicConstants[]
42 | private static readonly float BASE_RATE = 3.00f;
43 | private static readonly float FARE_PER_KM = 0.10f;
44 | private static readonly float DISCOUNT_RATE_CHILDREN = 0.25f;
45 | private static readonly float DISCOUNT_RATE_ELDERLY = 0.5f;
46 | private static readonly int MAXIMUM_AGE_CHILDREN = 12;
47 | private static readonly int MINIMUM_AGE_ELDERLY = 65;
48 |
49 | float CalculateFare(Customer c, long distance)
50 | {
51 | float travelledDistanceFare = distance * FARE_PER_KM;
52 | if (c.Age < MAXIMUM_AGE_CHILDREN)
53 | {
54 | travelledDistanceFare *= DISCOUNT_RATE_CHILDREN;
55 | }
56 | else
57 | if (c.Age >= MINIMUM_AGE_ELDERLY)
58 | {
59 | travelledDistanceFare *= DISCOUNT_RATE_ELDERLY;
60 | }
61 | return BASE_RATE + travelledDistanceFare;
62 | }
63 | // end::calculateFareDoNotUseMagicConstants[]
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/csharp/eu/sig/training/ch11/StandardContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace eu.sig.training.ch11 {
4 | public class StandardContext {
5 |
6 | // tag::validateFilterMap[]
7 | private void ValidateFilterMap(FilterMap filterMap) {
8 | // Validate the proposed filter mapping
9 | string filterName = filterMap.GetFilterName();
10 | string[] servletNames = filterMap.GetServletNames();
11 | string[] urlPatterns = filterMap.GetURLPatterns();
12 | if (FindFilterDef(filterName) == null)
13 | throw new Exception(
14 | sm.GetString("standardContext.filterMap.name", filterName));
15 |
16 | if (!filterMap.GetMatchAllServletNames() &&
17 | !filterMap.GetMatchAllUrlPatterns() &&
18 | (servletNames.Length == 0) && (urlPatterns.Length == 0))
19 | throw new Exception(
20 | sm.GetString("standardContext.filterMap.either"));
21 | // FIXME: Older spec revisions may still check this
22 | /*
23 | if ((servletNames.length != 0) && (urlPatterns.length != 0))
24 | throw new IllegalArgumentException
25 | (sm.getString("standardContext.filterMap.either"));
26 | */
27 | for (int i = 0; i < urlPatterns.Length; i++) {
28 | if (!ValidateURLPattern(urlPatterns[i])) {
29 | throw new Exception(
30 | sm.GetString("standardContext.filterMap.pattern",
31 | urlPatterns[i]));
32 | }
33 | }
34 | }
35 | // end::validateFilterMap[]
36 |
37 | public class GetStringObject {
38 | public string GetString(string s) {
39 | return s;
40 | }
41 |
42 | public string GetString(string s, object o) {
43 | return s;
44 | }
45 | }
46 |
47 | private GetStringObject sm = new GetStringObject();
48 |
49 | public class FilterMap {
50 |
51 | public bool GetMatchAllUrlPatterns() {
52 | return false;
53 | }
54 |
55 | public string[] GetURLPatterns() {
56 | return null;
57 | }
58 |
59 | public string[] GetServletNames() {
60 | return null;
61 | }
62 |
63 | public string GetFilterName() {
64 | return null;
65 | }
66 |
67 | public bool GetMatchAllServletNames() {
68 | return false;
69 | }
70 |
71 | }
72 |
73 | private bool ValidateURLPattern(string s) {
74 | return false;
75 | }
76 |
77 | private object FindFilterDef(string filterName) {
78 | return null;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/csharp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/BalancesServlet.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02;
2 |
3 | import java.io.IOException;
4 | import java.sql.Connection;
5 | import java.sql.DriverManager;
6 | import java.sql.ResultSet;
7 | import java.sql.SQLException;
8 | import java.util.Properties;
9 |
10 | import javax.servlet.ServletException;
11 | import javax.servlet.http.HttpServlet;
12 | import javax.servlet.http.HttpServletRequest;
13 | import javax.servlet.http.HttpServletResponse;
14 |
15 | public class BalancesServlet extends HttpServlet {
16 | private static final long serialVersionUID = 1L;
17 | private Properties conf;
18 |
19 | @Override
20 | // tag::doGet[]
21 | public void doGet(HttpServletRequest req, HttpServletResponse resp)
22 | throws ServletException, IOException {
23 | resp.setContentType("application/json");
24 | try {
25 | Connection conn = DriverManager.
26 | getConnection(this.conf.getProperty("handler.jdbcurl"));
27 | ResultSet results =
28 | conn.createStatement()
29 | .executeQuery(
30 | "SELECT account, balance FROM ACCTS WHERE id="
31 | + req.getParameter(conf.
32 | getProperty("request.parametername")));
33 | float totalBalance = 0;
34 | resp.getWriter().print("{\"balances\":[");
35 | while (results.next()) {
36 | // Assuming result is 9-digit bank account number,
37 | // validate with 11-test:
38 | int sum = 0;
39 | for (int i = 0; i < results.getString("account")
40 | .length(); i++) {
41 | sum = sum + (9 - i)
42 | * Character.getNumericValue(results.getString(
43 | "account").charAt(i));
44 | }
45 | if (sum % 11 == 0) {
46 | totalBalance += results.getFloat("balance");
47 | resp.getWriter().print(
48 | "{\"" + results.getString("account") + "\":"
49 | + results.getFloat("balance") + "}");
50 | }
51 | if (results.isLast()) {
52 | resp.getWriter().println("],");
53 | } else {
54 | resp.getWriter().print(",");
55 | }
56 | }
57 | resp.getWriter().println("\"total\":" + totalBalance + "}");
58 | } catch (SQLException e) {
59 | System.out.println("SQL exception: " + e.getMessage());
60 | }
61 | }
62 | // end::doGet[]
63 | }
64 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/BoardFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02;
2 |
3 | public class BoardFactory {
4 | // tag::createBoard[]
5 | public Board createBoard(Square[][] grid) {
6 | assert grid != null;
7 |
8 | Board board = new Board(grid);
9 |
10 | int width = board.getWidth();
11 | int height = board.getHeight();
12 | for (int x = 0; x < width; x++) {
13 | for (int y = 0; y < height; y++) {
14 | Square square = grid[x][y];
15 | for (Direction dir : Direction.values()) {
16 | int dirX = (width + x + dir.getDeltaX()) % width;
17 | int dirY = (height + y + dir.getDeltaY()) % height;
18 | Square neighbour = grid[dirX][dirY];
19 | square.link(neighbour, dir);
20 | }
21 | }
22 | }
23 |
24 | return board;
25 | }
26 | // end::createBoard[]
27 | }
28 |
29 | class Board {
30 | @SuppressWarnings("unused")
31 | public Board(Square[][] grid) {}
32 |
33 | public int getWidth() {
34 | return 0;
35 | }
36 |
37 | public int getHeight() {
38 | return 0;
39 | }
40 | }
41 |
42 | class Square {
43 | @SuppressWarnings("unused")
44 | public void link(Square neighbour, Direction dir) {}
45 | }
46 |
47 | class Direction {
48 |
49 | public static Direction[] values() {
50 | return null;
51 | }
52 |
53 | public int getDeltaY() {
54 | return 0;
55 | }
56 |
57 | public int getDeltaX() {
58 | return 0;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/Employees.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02;
2 |
3 | public class Employees {
4 | // tag::printDepartmentEmployees[]
5 | public static void printDepartmentEmployees(String department) {
6 | Query q = new Query();
7 | for (Employee e : q.addColumn("FamilyName")
8 | .addColumn("Initials")
9 | .addColumn("GivenName")
10 | .addColumn("AddressLine1")
11 | .addColumn("ZIPcode")
12 | .addColumn("City")
13 | .addTable("EMPLOYEES")
14 | .addWhere("EmployeeDep='" + department + "'")
15 | .execute()) {
16 | System.out.println("" + e.getAddressLine1()
18 | + "
" + e.getZipCode() + e.getCity() + "");
19 | }
20 | }
21 | // end::printDepartmentEmployees[]
22 | }
23 |
24 | class Query {
25 |
26 | @SuppressWarnings("unused")
27 | public Query addColumn(String string) {
28 | return null;
29 | }
30 |
31 | public Employee[] execute() {
32 | return null;
33 | }
34 |
35 | @SuppressWarnings("unused")
36 | public Query addWhere(String string) {
37 | return null;
38 | }
39 |
40 | @SuppressWarnings("unused")
41 | public Query addTable(String string) {
42 | return null;
43 | }
44 | }
45 |
46 | class Employee {
47 |
48 | public String getFamilyName() {
49 | return null;
50 | }
51 |
52 | public String getAddressLine1() {
53 | return null;
54 | }
55 |
56 | public String getZipCode() {
57 | return null;
58 | }
59 |
60 | public String getCity() {
61 | return null;
62 | }
63 |
64 | public String getInitials() {
65 | return null;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/Level.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02;
2 |
3 | import java.util.List;
4 |
5 | public class Level {
6 | private boolean inProgress;
7 | private final List observers;
8 |
9 | Level(List observers) {
10 | this.observers = observers;
11 | }
12 |
13 | // tag::start[]
14 | public void start() {
15 | if (inProgress) {
16 | return;
17 | }
18 | inProgress = true;
19 | // Update observers if player died:
20 | if (!isAnyPlayerAlive()) {
21 | for (LevelObserver o : observers) {
22 | o.levelLost();
23 | }
24 | }
25 | // Update observers if all pellets eaten:
26 | if (remainingPellets() == 0) {
27 | for (LevelObserver o : observers) {
28 | o.levelWon();
29 | }
30 | }
31 | }
32 | // end::start[]
33 |
34 | @SuppressWarnings("unused")
35 | // tag::updateObservers[]
36 | private void updateObservers() {
37 | // Update observers if player died:
38 | if (!isAnyPlayerAlive()) {
39 | for (LevelObserver o : observers) {
40 | o.levelLost();
41 | }
42 | }
43 | // Update observers if all pellets eaten:
44 | if (remainingPellets() == 0) {
45 | for (LevelObserver o : observers) {
46 | o.levelWon();
47 | }
48 | }
49 | }
50 | // end::updateObservers[]
51 |
52 | @SuppressWarnings("unused")
53 | // tag::updateObserversPlayerDied[]
54 | private void updateObserversPlayerDied() {
55 | if (!isAnyPlayerAlive()) {
56 | for (LevelObserver o : observers) {
57 | o.levelLost();
58 | }
59 | }
60 | }
61 |
62 | // end::updateObserversPlayerDied[]
63 |
64 | @SuppressWarnings("unused")
65 | // tag::updateObserversPelletsEaten[]
66 | private void updateObserversPelletsEaten() {
67 | if (remainingPellets() == 0) {
68 | for (LevelObserver o : observers) {
69 | o.levelWon();
70 | }
71 | }
72 | }
73 | // end::updateObserversPelletsEaten[]
74 |
75 | private int remainingPellets() {
76 | return 0;
77 | }
78 |
79 | private boolean isAnyPlayerAlive() {
80 | return false;
81 | }
82 | }
83 |
84 | class LevelObserver {
85 | public void levelLost() {}
86 | public void levelWon() {}
87 | }
88 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/LevelHelper.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02;
2 |
3 | public class LevelHelper {
4 | private boolean inProgress;
5 |
6 | // tag::firstStepStart[]
7 | public void start() {
8 | if (inProgress) {
9 | return;
10 | }
11 | inProgress = true;
12 | }
13 | // end::firstStepStart[]
14 | }
15 |
16 | class ExtractMethod {
17 | private boolean inProgress;
18 |
19 | // tag::extractMethodStart[]
20 | public void start() {
21 | if (inProgress) {
22 | return;
23 | }
24 | inProgress = true;
25 | updateObservers();
26 | }
27 | // end::extractMethodStart[]
28 |
29 | // tag::updateObservers[]
30 | private void updateObservers() {
31 | updateObserversPlayerDied();
32 | updateObserversPelletsEaten();
33 | }
34 | // end::updateObservers[]
35 |
36 | private void updateObserversPlayerDied() {}
37 |
38 | private void updateObserversPelletsEaten() {}
39 | }
40 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/v1/BoardFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02.v1;
2 |
3 | public class BoardFactory {
4 | // tag::createBoard[]
5 | public Board createBoard(Square[][] grid) {
6 | assert grid != null;
7 |
8 | Board board = new Board(grid);
9 |
10 | int width = board.getWidth();
11 | int height = board.getHeight();
12 | for (int x = 0; x < width; x++) {
13 | for (int y = 0; y < height; y++) {
14 | Square square = grid[x][y];
15 | for (Direction dir : Direction.values()) {
16 | setLink(square, dir, x, y, width, height, grid);
17 | }
18 | }
19 | }
20 |
21 | return board;
22 | }
23 | // end::createBoard[]
24 |
25 | // tag::setLink[]
26 | private void setLink(Square square, Direction dir, int x, int y, int width,
27 | int height, Square[][] grid) {
28 | int dirX = (width + x + dir.getDeltaX()) % width;
29 | int dirY = (height + y + dir.getDeltaY()) % height;
30 | Square neighbour = grid[dirX][dirY];
31 | square.link(neighbour, dir);
32 | }
33 | // end::setLink[]
34 | }
35 |
36 | class Board {
37 | @SuppressWarnings("unused")
38 | public Board(Square[][] grid) {}
39 |
40 | public int getWidth() {
41 | return 0;
42 | }
43 |
44 | public int getHeight() {
45 | return 0;
46 | }
47 | }
48 |
49 | class Square {
50 | @SuppressWarnings("unused")
51 | public void link(Square neighbour, Direction dir) {}
52 | }
53 |
54 | class Direction {
55 |
56 | public static Direction[] values() {
57 | return null;
58 | }
59 |
60 | public int getDeltaY() {
61 | return 0;
62 | }
63 |
64 | public int getDeltaX() {
65 | return 0;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch02/v2/BoardFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch02.v2;
2 |
3 | public class BoardFactory {
4 | // tag::createBoard[]
5 | public Board createBoard(Square[][] grid) {
6 | return new BoardCreator(grid).create();
7 | }
8 | // end::createBoard[]
9 | }
10 |
11 | // tag::BoardCreator[]
12 | class BoardCreator {
13 | private Square[][] grid;
14 | private Board board;
15 | private int width;
16 | private int height;
17 |
18 | BoardCreator(Square[][] grid) {
19 | assert grid != null;
20 | this.grid = grid;
21 | this.board = new Board(grid);
22 | this.width = board.getWidth();
23 | this.height = board.getHeight();
24 | }
25 |
26 | Board create() {
27 | for (int x = 0; x < width; x++) {
28 | for (int y = 0; y < height; y++) {
29 | Square square = grid[x][y];
30 | for (Direction dir : Direction.values()) {
31 | setLink(square, dir, x, y);
32 | }
33 | }
34 | }
35 | return this.board;
36 | }
37 |
38 | private void setLink(Square square, Direction dir, int x, int y) {
39 | int dirX = (width + x + dir.getDeltaX()) % width;
40 | int dirY = (height + y + dir.getDeltaY()) % height;
41 | Square neighbour = grid[dirX][dirY];
42 | square.link(neighbour, dir);
43 | }
44 | }
45 |
46 | // end::BoardCreator[]
47 |
48 | class Board {
49 | @SuppressWarnings("unused")
50 | public Board(Square[][] grid) {}
51 |
52 | public int getWidth() {
53 | return 0;
54 | }
55 |
56 | public int getHeight() {
57 | return 0;
58 | }
59 | }
60 |
61 | class Square {
62 | @SuppressWarnings("unused")
63 | public void link(Square neighbour, Direction dir) {}
64 | }
65 |
66 | class Direction {
67 |
68 | public static Direction[] values() {
69 | return null;
70 | }
71 |
72 | public int getDeltaY() {
73 | return 0;
74 | }
75 |
76 | public int getDeltaX() {
77 | return 0;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/Flag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class Flag {
8 | private final List colors;
9 |
10 | public Flag(Color... colors) {
11 | this.colors = Arrays.asList(colors);
12 | }
13 |
14 | public List getColors() {
15 | return colors;
16 | }
17 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/FlagFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class FlagFactory {
8 |
9 | // tag::getFlag[]
10 | public List getFlagColors(Nationality nationality) {
11 | List result;
12 | switch (nationality) {
13 | case DUTCH:
14 | result = Arrays.asList(Color.RED, Color.WHITE, Color.BLUE);
15 | break;
16 | case GERMAN:
17 | result = Arrays.asList(Color.BLACK, Color.RED, Color.YELLOW);
18 | break;
19 | case BELGIAN:
20 | result = Arrays.asList(Color.BLACK, Color.YELLOW, Color.RED);
21 | break;
22 | case FRENCH:
23 | result = Arrays.asList(Color.BLUE, Color.WHITE, Color.RED);
24 | break;
25 | case ITALIAN:
26 | result = Arrays.asList(Color.GREEN, Color.WHITE, Color.RED);
27 | break;
28 | case UNCLASSIFIED:
29 | default:
30 | result = Arrays.asList(Color.GRAY);
31 | break;
32 | }
33 | return result;
34 | }
35 | // end::getFlag[]
36 |
37 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/FlagFactoryOops.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | public class FlagFactoryOops {
7 | private static class Color extends java.awt.Color {
8 | private static final long serialVersionUID = 1L;
9 | public static Color BLACK = getColor(java.awt.Color.BLACK);
10 | public static Color BLUE = getColor(java.awt.Color.BLUE);
11 | public static Color RED = getColor(java.awt.Color.RED);
12 | public static Color GREEN = getColor(java.awt.Color.GREEN);
13 | public static Color GRAY = getColor(java.awt.Color.GRAY);
14 | public static Color LIGHT_BLUE = getColor(new java.awt.Color(0, 163, 224));
15 | public static Color WHITE = getColor(java.awt.Color.WHITE);
16 | public static Color YELLOW = getColor(java.awt.Color.YELLOW);
17 |
18 | public Color(java.awt.Color realColor) {
19 | super(realColor.getRGB());
20 | }
21 |
22 | public static Color getColor(java.awt.Color c) {
23 | return new Color(c);
24 | }
25 | }
26 |
27 | public List getFlagColors(Nationality nationality) {
28 | List result;
29 | switch (nationality) {
30 | // tag::getFlag[]
31 | case DUTCH:
32 | result = Arrays.asList(Color.RED, Color.WHITE, Color.BLUE);
33 | case LUXEMBOURGER:
34 | result = Arrays.asList(Color.RED, Color.WHITE, Color.LIGHT_BLUE);
35 | break;
36 | case GERMAN:
37 | // end::getFlag[]
38 | result = Arrays.asList(Color.BLACK, Color.RED, Color.YELLOW);
39 | break;
40 | case BELGIAN:
41 | result = Arrays.asList(Color.BLACK, Color.YELLOW, Color.RED);
42 | break;
43 | case FRENCH:
44 | result = Arrays.asList(Color.BLUE, Color.WHITE, Color.RED);
45 | break;
46 | case ITALIAN:
47 | result = Arrays.asList(Color.GREEN, Color.WHITE, Color.RED);
48 | break;
49 | case UNCLASSIFIED:
50 | default:
51 | result = Arrays.asList(Color.GRAY);
52 | break;
53 | }
54 | return result;
55 | }
56 |
57 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/FlagFactoryWithMap.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import static eu.sig.training.ch03.Nationality.BELGIAN;
4 | import static eu.sig.training.ch03.Nationality.DUTCH;
5 | import static eu.sig.training.ch03.Nationality.FRENCH;
6 | import static eu.sig.training.ch03.Nationality.GERMAN;
7 | import static eu.sig.training.ch03.Nationality.ITALIAN;
8 |
9 | import java.awt.Color;
10 | import java.util.Arrays;
11 | import java.util.HashMap;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class FlagFactoryWithMap {
16 |
17 | // tag::getFlag[]
18 | private static Map> FLAGS =
19 | new HashMap>();
20 |
21 | static {
22 | FLAGS.put(DUTCH, Arrays.asList(Color.RED, Color.WHITE, Color.BLUE));
23 | FLAGS.put(GERMAN, Arrays.asList(Color.BLACK, Color.RED, Color.YELLOW));
24 | FLAGS.put(BELGIAN, Arrays.asList(Color.BLACK, Color.YELLOW, Color.RED));
25 | FLAGS.put(FRENCH, Arrays.asList(Color.BLUE, Color.WHITE, Color.RED));
26 | FLAGS.put(ITALIAN, Arrays.asList(Color.GREEN, Color.WHITE, Color.RED));
27 | }
28 |
29 | public List getFlagColors(Nationality nationality) {
30 | List colors = FLAGS.get(nationality);
31 | return colors != null ? colors : Arrays.asList(Color.GRAY);
32 | }
33 | // end::getFlag[]
34 |
35 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/Nationality.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | public enum Nationality {
4 | DUTCH, GERMAN, BELGIAN, LUXEMBOURGER, FRENCH, ITALIAN, UNCLASSIFIED
5 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/binarytree/BinaryTreeNode.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree;
2 |
3 | public class BinaryTreeNode> {
4 | private final T value;
5 | private BinaryTreeNode left;
6 | private BinaryTreeNode right;
7 |
8 | public BinaryTreeNode(T value) {
9 | this.value = value;
10 | }
11 |
12 | public void insert(T value) {
13 | if (value.compareTo(this.value) < 0) {
14 | if (left != null) {
15 | left.insert(value);
16 | } else {
17 | left = new BinaryTreeNode(value);
18 | }
19 | } else {
20 | if (right != null) {
21 | right.insert(value);
22 | } else {
23 | right = new BinaryTreeNode(value);
24 | }
25 | }
26 | }
27 |
28 | public BinaryTreeNode getLeft() {
29 | return left;
30 | }
31 |
32 | public BinaryTreeNode getRight() {
33 | return right;
34 | }
35 |
36 | public T getValue() {
37 | return value;
38 | }
39 |
40 | public boolean isLeaf() {
41 | return left == null && right == null;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/binarytree/TreeException.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree;
2 |
3 | @SuppressWarnings("serial")
4 | public class TreeException extends RuntimeException {
5 | public TreeException(String msg) {
6 | super(msg);
7 | }
8 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/binarytree/v1/BinaryTreeSearch.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree.v1;
2 |
3 | import eu.sig.training.ch03.binarytree.TreeException;
4 | import eu.sig.training.ch03.binarytree.BinaryTreeNode;
5 |
6 | public class BinaryTreeSearch {
7 |
8 | // tag::calculateDepth[]
9 | public static int calculateDepth(BinaryTreeNode t, int n) {
10 | int depth = 0;
11 | if (t.getValue() == n) {
12 | return depth;
13 | } else {
14 | if (n < t.getValue()) {
15 | BinaryTreeNode left = t.getLeft();
16 | if (left == null) {
17 | throw new TreeException("Value not found in tree!");
18 | } else {
19 | return 1 + calculateDepth(left, n);
20 | }
21 | } else {
22 | BinaryTreeNode right = t.getRight();
23 | if (right == null) {
24 | throw new TreeException("Value not found in tree!");
25 | } else {
26 | return 1 + calculateDepth(right, n);
27 | }
28 | }
29 | }
30 | }
31 | // end::calculateDepth[]
32 | }
33 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/binarytree/v2/BinaryTreeSearch.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree.v2;
2 |
3 | import eu.sig.training.ch03.binarytree.BinaryTreeNode;
4 | import eu.sig.training.ch03.binarytree.TreeException;
5 |
6 | public class BinaryTreeSearch {
7 |
8 | // tag::calculateDepth[]
9 | public static int calculateDepth(BinaryTreeNode t, int n) {
10 | int depth = 0;
11 | if (t.getValue() == n)
12 | return depth;
13 | if (n < t.getValue() && t.getLeft() != null)
14 | return 1 + calculateDepth(t.getLeft(), n);
15 | if (n > t.getValue() && t.getRight() != null)
16 | return 1 + calculateDepth(t.getRight(), n);
17 | throw new TreeException("Value not found in tree!");
18 | }
19 | // end::calculateDepth[]
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/binarytree/v3/BinaryTreeSearch.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree.v3;
2 |
3 | import eu.sig.training.ch03.binarytree.BinaryTreeNode;
4 | import eu.sig.training.ch03.binarytree.TreeException;
5 |
6 | public class BinaryTreeSearch {
7 |
8 | // tag::calculateDepth[]
9 | public static int calculateDepth(BinaryTreeNode t, int n) {
10 | int depth = 0;
11 | if (t.getValue() == n)
12 | return depth;
13 | else
14 | return traverseByValue(t, n);
15 | }
16 |
17 | private static int traverseByValue(BinaryTreeNode t, int n) {
18 | BinaryTreeNode childNode = getChildNode(t, n);
19 | if (childNode == null) {
20 | throw new TreeException("Value not found in tree!");
21 | } else {
22 | return 1 + calculateDepth(childNode, n);
23 | }
24 | }
25 |
26 | private static BinaryTreeNode getChildNode(
27 | BinaryTreeNode t, int n) {
28 | if (n < t.getValue()) {
29 | return t.getLeft();
30 | } else {
31 | return t.getRight();
32 | }
33 | }
34 | // end::calculateDepth[]
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/BelgianFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class BelgianFlag implements Flag {
8 | public List getColors() {
9 | return Arrays.asList(Color.BLACK, Color.RED, Color.YELLOW);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/DefaultFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class DefaultFlag implements Flag {
8 | public List getColors() {
9 | return Arrays.asList(Color.GRAY);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/DutchFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | // tag::DutchFlag[]
8 | public class DutchFlag implements Flag {
9 | public List getColors() {
10 | return Arrays.asList(Color.RED, Color.WHITE, Color.BLUE);
11 | }
12 | }
13 | // end::DutchFlag[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/Flag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.List;
5 |
6 | // tag::Flag[]
7 | public interface Flag {
8 | List getColors();
9 | }
10 | // end::Flag[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/FlagFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import static eu.sig.training.ch03.Nationality.BELGIAN;
4 | import static eu.sig.training.ch03.Nationality.DUTCH;
5 | import static eu.sig.training.ch03.Nationality.FRENCH;
6 | import static eu.sig.training.ch03.Nationality.GERMAN;
7 | import static eu.sig.training.ch03.Nationality.ITALIAN;
8 |
9 | import java.awt.Color;
10 | import java.util.HashMap;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | import eu.sig.training.ch03.Nationality;
15 |
16 | public class FlagFactory {
17 |
18 | // tag::getFlag[]
19 | private static final Map FLAGS =
20 | new HashMap();
21 |
22 | static {
23 | FLAGS.put(DUTCH, new DutchFlag());
24 | FLAGS.put(GERMAN, new GermanFlag());
25 | FLAGS.put(BELGIAN, new BelgianFlag());
26 | FLAGS.put(FRENCH, new FrenchFlag());
27 | FLAGS.put(ITALIAN, new ItalianFlag());
28 | }
29 |
30 | public List getFlagColors(Nationality nationality) {
31 | Flag flag = FLAGS.get(nationality);
32 | flag = flag != null ? flag : new DefaultFlag();
33 | return flag.getColors();
34 | }
35 | // end::getFlag[]
36 |
37 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/FrenchFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 |
8 | public class FrenchFlag implements Flag {
9 | public List getColors() {
10 | return Arrays.asList(Color.BLUE, Color.WHITE, Color.RED);
11 | }
12 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/GermanFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | public class GermanFlag implements Flag {
8 | public List getColors() {
9 | return Arrays.asList(Color.BLACK, Color.RED, Color.YELLOW);
10 | }
11 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch03/withmapandtypes/ItalianFlag.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.withmapandtypes;
2 |
3 | import java.awt.Color;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | // tag::ItalianFlag[]
8 | public class ItalianFlag implements Flag {
9 | public List getColors() {
10 | return Arrays.asList(Color.GREEN, Color.WHITE, Color.RED);
11 | }
12 | }
13 | // end::ItalianFlag[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/BusinessException.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04;
2 |
3 | public class BusinessException extends Exception {
4 | private static final long serialVersionUID = 1L;
5 |
6 | public BusinessException(String message) {
7 | super(message);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/Clones.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04;
2 |
3 | public class Clones {
4 | private String givenName;
5 | private String familyName;
6 | private float pageWidthInCm;
7 |
8 | // tag::one-six-line-clone[]
9 | public void setGivenName(String givenName) {
10 | this.givenName = givenName;
11 | }
12 |
13 | public void setFamilyName(String familyName) {
14 | this.familyName = familyName;
15 | }
16 | // end::one-six-line-clone[]
17 |
18 | public String getGivenName() {
19 | return givenName;
20 | }
21 |
22 | public String getFamilyName() {
23 | return familyName;
24 | }
25 |
26 | // tag::type-2-clone[]
27 | public void setPageWidthInInches(float newWidth) {
28 | float cmPerInch = 2.54f;
29 | this.pageWidthInCm = newWidth * cmPerInch;
30 | // A few more lines.
31 | }
32 |
33 | public void setPageWidthInPoints(float newWidth) {
34 | float cmPerPoint = 0.0352777f;
35 | this.pageWidthInCm = newWidth * cmPerPoint;
36 | // A few more lines (same as in setPageWidthInInches).
37 | }
38 | // end::type-2-clone[]
39 |
40 | public float getPageWidthInCm() {
41 | return pageWidthInCm;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/Money.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04;
2 |
3 | public class Money {
4 | @SuppressWarnings("unused")
5 | public boolean greaterThan(int limit) {
6 | return true;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v1/Accounts.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v1;
2 |
3 | public class Accounts {
4 | @SuppressWarnings("unused")
5 | public static CheckingAccount findAcctByNumber(String number) {
6 | return new CheckingAccount();
7 | }
8 |
9 | // tag::isValid[]
10 | public static boolean isValid(String number) {
11 | int sum = 0;
12 | for (int i = 0; i < number.length(); i++) {
13 | sum = sum + (9 - i) * Character.getNumericValue(number.charAt(i));
14 | }
15 | return sum % 11 == 0;
16 | }
17 | // end::isValid[]
18 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v1/CheckingAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v1;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::CheckingAccount[]
7 | public class CheckingAccount {
8 | private int transferLimit = 100;
9 |
10 | public Transfer makeTransfer(String counterAccount, Money amount)
11 | throws BusinessException {
12 | // 1. Check withdrawal limit:
13 | if (amount.greaterThan(this.transferLimit)) {
14 | throw new BusinessException("Limit exceeded!");
15 | }
16 | // 2. Assuming result is 9-digit bank account number, validate 11-test:
17 | int sum = 0;
18 | for (int i = 0; i < counterAccount.length(); i++) {
19 | sum = sum + (9-i) * Character.getNumericValue(
20 | counterAccount.charAt(i));
21 | }
22 | if (sum % 11 == 0) {
23 | // 3. Look up counter account and make transfer object:
24 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
25 | Transfer result = new Transfer(this, acct, amount);
26 | return result;
27 | } else {
28 | throw new BusinessException("Invalid account number!");
29 | }
30 | }
31 | }
32 | // end::CheckingAccount[]
33 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v1/SavingsAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v1;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::SavingsAccount[]
7 | public class SavingsAccount {
8 | CheckingAccount registeredCounterAccount;
9 |
10 | public Transfer makeTransfer(String counterAccount, Money amount)
11 | throws BusinessException {
12 | // 1. Assuming result is 9-digit bank account number, validate 11-test:
13 | int sum = 0; // <1>
14 | for (int i = 0; i < counterAccount.length(); i++) {
15 | sum = sum + (9 - i) * Character.getNumericValue(
16 | counterAccount.charAt(i));
17 | }
18 | if (sum % 11 == 0) {
19 | // 2. Look up counter account and make transfer object:
20 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
21 | Transfer result = new Transfer(this, acct, amount); // <2>
22 | // 3. Check whether withdrawal is to registered counter account:
23 | if (result.getCounterAccount().equals(this.registeredCounterAccount))
24 | {
25 | return result;
26 | } else {
27 | throw new BusinessException("Counter-account not registered!");
28 | }
29 | } else {
30 | throw new BusinessException("Invalid account number!!");
31 | }
32 | }
33 | }
34 | // end::SavingsAccount[]
35 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v1/Transfer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v1;
2 |
3 | import eu.sig.training.ch04.Money;
4 |
5 | public class Transfer {
6 | CheckingAccount counterAccount;
7 |
8 | @SuppressWarnings("unused")
9 | public Transfer(CheckingAccount acct1, CheckingAccount acct2, Money m) {}
10 |
11 | @SuppressWarnings("unused")
12 | public Transfer(SavingsAccount acct1, CheckingAccount acct2, Money m) {}
13 |
14 | public CheckingAccount getCounterAccount() {
15 | return this.counterAccount;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v2/Accounts.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v2;
2 |
3 | public class Accounts {
4 | @SuppressWarnings("unused")
5 | public static CheckingAccount findAcctByNumber(String number) {
6 | return new CheckingAccount();
7 | }
8 |
9 | // tag::isValid[]
10 | public static boolean isValid(String number) {
11 | int sum = 0;
12 | for (int i = 0; i < number.length(); i++) {
13 | sum = sum + (9 - i) * Character.getNumericValue(number.charAt(i));
14 | }
15 | return sum % 11 == 0;
16 | }
17 | // end::isValid[]
18 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v2/CheckingAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v2;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::CheckingAccount[]
7 | public class CheckingAccount {
8 | private int transferLimit = 100;
9 |
10 | public Transfer makeTransfer(String counterAccount, Money amount)
11 | throws BusinessException {
12 | // 1. Check withdrawal limit:
13 | if (amount.greaterThan(this.transferLimit)) {
14 | throw new BusinessException("Limit exceeded!");
15 | }
16 | if (Accounts.isValid(counterAccount)) { // <1>
17 | // 2. Look up counter account and make transfer object:
18 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
19 | Transfer result = new Transfer(this, acct, amount); // <2>
20 | return result;
21 | } else {
22 | throw new BusinessException("Invalid account number!");
23 | }
24 | }
25 |
26 | }
27 | // end::CheckingAccount[]
28 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v2/SavingsAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v2;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::SavingsAccount[]
7 | public class SavingsAccount {
8 | CheckingAccount registeredCounterAccount;
9 |
10 | public Transfer makeTransfer(String counterAccount, Money amount)
11 | throws BusinessException {
12 | // 1. Assuming result is 9-digit bank account number,
13 | // validate with 11-test:
14 | if (Accounts.isValid(counterAccount)) { // <1>
15 | // 2. Look up counter account and make transfer object:
16 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
17 | Transfer result = new Transfer(this, acct, amount); // <2>
18 | if (result.getCounterAccount().equals(this.registeredCounterAccount))
19 | {
20 | return result;
21 | } else {
22 | throw new BusinessException("Counter-account not registered!");
23 | }
24 | } else {
25 | throw new BusinessException("Invalid account number!!");
26 | }
27 | }
28 |
29 | }
30 | // end::SavingsAccount[]
31 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v2/Transfer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v2;
2 |
3 | import eu.sig.training.ch04.Money;
4 |
5 | public class Transfer {
6 | CheckingAccount counterAccount;
7 |
8 | @SuppressWarnings("unused")
9 | public Transfer(CheckingAccount acct1, CheckingAccount acct2, Money m) {}
10 |
11 | @SuppressWarnings("unused")
12 | public Transfer(SavingsAccount acct1, CheckingAccount acct2, Money m) {}
13 |
14 | public CheckingAccount getCounterAccount() {
15 | return this.counterAccount;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v3/Account.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::Account[]
7 | public class Account {
8 | public Transfer makeTransfer(String counterAccount, Money amount)
9 | throws BusinessException {
10 | // 1. Assuming result is 9-digit bank account number, validate 11-test:
11 | int sum = 0; // <1>
12 | for (int i = 0; i < counterAccount.length(); i++) {
13 | sum = sum + (9 - i) * Character.
14 | getNumericValue(counterAccount.charAt(i));
15 | }
16 | if (sum % 11 == 0) {
17 | // 2. Look up counter account and make transfer object:
18 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
19 | Transfer result = new Transfer(this, acct, amount); // <2>
20 | return result;
21 | } else {
22 | throw new BusinessException("Invalid account number!");
23 | }
24 | }
25 | }
26 | // end::Account[]
27 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v3/Accounts.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | import eu.sig.training.ch04.BusinessException;
7 |
8 | public class Accounts {
9 |
10 | // The Java version of the Account class does not have a string Number as property,
11 | // and the Java edition of the book is already in print. So we add an external
12 | // association of Accounts and their numbers.
13 | public static Map ACCOUNTS = new HashMap();
14 | public static Map NUMBERS = new HashMap();
15 |
16 | // @SuppressWarnings("unused")
17 | public static CheckingAccount findAcctByNumber(String number)
18 | throws BusinessException {
19 | Object myAccount = ACCOUNTS.get(number);
20 | if (myAccount instanceof CheckingAccount) {
21 | return (CheckingAccount)myAccount;
22 | } else {
23 | throw new BusinessException("Not a checking account.");
24 | }
25 | }
26 |
27 | public static T makeAccount(Class clazz,
28 | String number) {
29 | try {
30 | T myAccount = clazz.newInstance();
31 | ACCOUNTS.put(number, myAccount);
32 | NUMBERS.put(myAccount, number);
33 | return myAccount;
34 | } catch (Exception e) {
35 | System.exit(1);
36 | return null;
37 | }
38 | }
39 |
40 | public static String getAccountNumber(Account acct) {
41 | return NUMBERS.get(acct);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v3/CheckingAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::CheckingAccount[]
7 | public class CheckingAccount extends Account {
8 | private int transferLimit = 100;
9 |
10 | @Override
11 | public Transfer makeTransfer(String counterAccount, Money amount)
12 | throws BusinessException {
13 | if (amount.greaterThan(this.transferLimit)) {
14 | throw new BusinessException("Limit exceeded!");
15 | }
16 | return super.makeTransfer(counterAccount, amount);
17 | }
18 | }
19 | // end::CheckingAccount[]
20 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v3/SavingsAccount.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 |
6 | // tag::SavingsAccount[]
7 | public class SavingsAccount extends Account {
8 | CheckingAccount registeredCounterAccount;
9 |
10 | @Override
11 | public Transfer makeTransfer(String counterAccount, Money amount)
12 | throws BusinessException {
13 | Transfer result = super.makeTransfer(counterAccount, amount);
14 | if (result.getCounterAccount().equals(this.registeredCounterAccount)) {
15 | return result;
16 | } else {
17 | throw new BusinessException("Counter-account not registered!");
18 | }
19 | }
20 | }
21 | // end::SavingsAccount[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v3/Transfer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import eu.sig.training.ch04.Money;
4 |
5 | public class Transfer {
6 | CheckingAccount counterAccount;
7 |
8 | @SuppressWarnings("unused")
9 | public Transfer(Account acct1, CheckingAccount acct2, Money m) {
10 | this.counterAccount = acct2;
11 | }
12 |
13 | public CheckingAccount getCounterAccount() {
14 | return this.counterAccount;
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v4/Account.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v4;
2 |
3 | import eu.sig.training.ch04.BusinessException;
4 | import eu.sig.training.ch04.Money;
5 | import eu.sig.training.ch04.v3.CheckingAccount;
6 |
7 | // tag::Account[]
8 | public class Account {
9 | public Transfer makeTransfer(String counterAccount, Money amount)
10 | throws BusinessException {
11 | if (isValid(counterAccount)) {
12 | CheckingAccount acct = Accounts.findAcctByNumber(counterAccount);
13 | return new Transfer(this, acct, amount);
14 | } else {
15 | throw new BusinessException("Invalid account number!");
16 | }
17 | }
18 |
19 | public static boolean isValid(String number) {
20 | int sum = 0;
21 | for (int i = 0; i < number.length(); i++) {
22 | sum = sum + (9 - i) * Character.getNumericValue(number.charAt(i));
23 | }
24 | return sum % 11 == 0;
25 | }
26 | }
27 | // end::Account[]
28 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v4/Accounts.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v4;
2 |
3 | import eu.sig.training.ch04.v3.CheckingAccount;
4 |
5 | public class Accounts {
6 | @SuppressWarnings("unused")
7 | public static CheckingAccount findAcctByNumber(String number) {
8 | return new CheckingAccount();
9 | }
10 |
11 | // Version that should make tests succeed (not used in book):
12 | public static boolean isValid(String number) {
13 | if (number.length() != 9) {
14 | return false;
15 | }
16 | int sum = 0;
17 | for (int i = 0; i < number.length(); i++) {
18 | if (!Character.isDigit(number.charAt(i))) {
19 | return false;
20 | }
21 | sum = sum + (9 - i) * Character.getNumericValue(number.charAt(i));
22 | }
23 | return sum % 11 == 0;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch04/v4/Transfer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v4;
2 |
3 | import eu.sig.training.ch04.Money;
4 | import eu.sig.training.ch04.v3.CheckingAccount;
5 |
6 | public class Transfer {
7 | CheckingAccount counterAccount;
8 |
9 | @SuppressWarnings("unused")
10 | public Transfer(Account acct1, CheckingAccount acct2, Money m) {}
11 |
12 | public CheckingAccount getCounterAccount() {
13 | return this.counterAccount;
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/boardpanel/v1/BoardPanel.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.boardpanel.v1;
2 |
3 | import java.awt.Graphics;
4 | import java.util.List;
5 |
6 | public class BoardPanel {
7 | @SuppressWarnings("unused")
8 | // tag::render[]
9 | /**
10 | * Renders a single square on the given graphics context on the specified
11 | * rectangle.
12 | *
13 | * @param square
14 | * The square to render.
15 | * @param g
16 | * The graphics context to draw on.
17 | * @param x
18 | * The x position to start drawing.
19 | * @param y
20 | * The y position to start drawing.
21 | * @param w
22 | * The width of this square (in pixels).
23 | * @param h
24 | * The height of this square (in pixels).
25 | */
26 | private void render(Square square, Graphics g, int x, int y, int w, int h) {
27 | square.getSprite().draw(g, x, y, w, h);
28 | for (Unit unit : square.getOccupants()) {
29 | unit.getSprite().draw(g, x, y, w, h);
30 | }
31 | }
32 | // end::render[]
33 |
34 | private class Sprite {
35 | @SuppressWarnings("unused")
36 | public void draw(Graphics g, int x, int y, int w, int h) {
37 |
38 | }
39 | }
40 |
41 | private class Unit {
42 | public Sprite getSprite() {
43 | return null;
44 | }
45 | }
46 |
47 | private class Square extends Unit {
48 |
49 | public List getOccupants() {
50 | return null;
51 | }
52 |
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/boardpanel/v2/BoardPanel.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.boardpanel.v2;
2 |
3 | import java.awt.Graphics;
4 | import java.awt.Point;
5 | import java.util.List;
6 |
7 | public class BoardPanel {
8 | @SuppressWarnings("unused")
9 | // tag::render[]
10 | /**
11 | * Renders a single square on the given graphics context on the specified
12 | * rectangle.
13 | *
14 | * @param square
15 | * The square to render.
16 | * @param g
17 | * The graphics context to draw on.
18 | * @param r
19 | * The position and dimension for rendering the square.
20 | */
21 | private void render(Square square, Graphics g, Rectangle r) {
22 | Point position = r.getPosition();
23 | square.getSprite().draw(g, position.x, position.y, r.getWidth(),
24 | r.getHeight());
25 | for (Unit unit : square.getOccupants()) {
26 | unit.getSprite().draw(g, position.x, position.y, r.getWidth(),
27 | r.getHeight());
28 | }
29 | }
30 | // end::render[]
31 |
32 | private class Sprite {
33 | @SuppressWarnings("unused")
34 | public void draw(Graphics g, int x, int y, int w, int h) {
35 |
36 | }
37 | }
38 |
39 | private class Unit {
40 | public Sprite getSprite() {
41 | return null;
42 | }
43 | }
44 |
45 | private class Square extends Unit {
46 |
47 | public List getOccupants() {
48 | return null;
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/boardpanel/v2/Rectangle.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.boardpanel.v2;
2 |
3 | import java.awt.Point;
4 |
5 | // tag::Rectangle[]
6 | public class Rectangle {
7 | private final Point position;
8 | private final int width;
9 | private final int height;
10 |
11 | public Rectangle(Point position, int width, int height) {
12 | this.position = position;
13 | this.width = width;
14 | this.height = height;
15 | }
16 |
17 | public Point getPosition() {
18 | return position;
19 | }
20 |
21 | public int getWidth() {
22 | return width;
23 | }
24 |
25 | public int getHeight() {
26 | return height;
27 | }
28 | }
29 | // end::Rectangle[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/boardpanel/v3/BoardPanel.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.boardpanel.v3;
2 |
3 | import java.awt.Graphics;
4 | import java.awt.Point;
5 | import java.util.List;
6 |
7 | import eu.sig.training.ch05.boardpanel.v2.Rectangle;
8 |
9 | public class BoardPanel {
10 | @SuppressWarnings("unused")
11 | /**
12 | * Renders a single square on the given graphics context on the specified
13 | * rectangle.
14 | *
15 | * @param square
16 | * The square to render.
17 | * @param g
18 | * The graphics context to draw on.
19 | * @param r
20 | * The position and dimension for rendering the square.
21 | */
22 | // tag::render[]
23 | private void render(Square square, Graphics g, Rectangle r) {
24 | Point position = r.getPosition();
25 | square.getSprite().draw(g, r);
26 | for (Unit unit : square.getOccupants()) {
27 | unit.getSprite().draw(g, r);
28 | }
29 | }
30 | // end::render[]
31 |
32 | private class Sprite {
33 | @SuppressWarnings("unused")
34 | public void draw(Graphics g, Rectangle r) {
35 |
36 | }
37 | }
38 |
39 | private class Unit {
40 | public Sprite getSprite() {
41 | return null;
42 | }
43 | }
44 |
45 | private class Square extends Unit {
46 |
47 | public List getOccupants() {
48 | return null;
49 | }
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/buildandsendmail/v1/BuildAndSendMail.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.buildandsendmail.v1;
2 |
3 | public class BuildAndSendMail {
4 | // tag::buildAndSendMail[]
5 | public void buildAndSendMail(MailMan m, String firstName, String lastName,
6 | String division, String subject, MailFont font, String message1,
7 | String message2, String message3) {
8 | // Format the email address
9 | String mId = firstName.charAt(0) + "." + lastName.substring(0, 7) + "@"
10 | + division.substring(0, 5) + ".compa.ny";
11 | // Format the message given the content type and raw message
12 | MailMessage mMessage = formatMessage(font,
13 | message1 + message2 + message3);
14 | // Send message
15 | m.send(mId, subject, mMessage);
16 | }
17 | // end::buildAndSendMail[]
18 |
19 | @SuppressWarnings("unused")
20 | private MailMessage formatMessage(MailFont font, String string) {
21 | return null;
22 | }
23 |
24 | private class MailMan {
25 |
26 | @SuppressWarnings("unused")
27 | public void send(String mId, String subject, MailMessage mMessage) {}
28 |
29 | }
30 |
31 | private class MailFont {
32 |
33 | }
34 |
35 | private class MailMessage {
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/buildandsendmail/v2/BuildAndSendMail.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.buildandsendmail.v2;
2 |
3 | @SuppressWarnings("unused")
4 | public class BuildAndSendMail {
5 |
6 | // tag::buildAndSendMail[]
7 | public void buildAndSendMail(MailMan m, MailAddress mAddress,
8 | MailBody mBody) {
9 | // Build the mail
10 | Mail mail = new Mail(mAddress, mBody);
11 | // Send the mail
12 | m.sendMail(mail);
13 | }
14 |
15 | private class Mail {
16 | private MailAddress address;
17 | private MailBody body;
18 |
19 | private Mail(MailAddress mAddress, MailBody mBody) {
20 | this.address = mAddress;
21 | this.body = mBody;
22 | }
23 | }
24 |
25 | private class MailBody {
26 | String subject;
27 | MailMessage message;
28 |
29 | public MailBody(String subject, MailMessage message) {
30 | this.subject = subject;
31 | this.message = message;
32 | }
33 | }
34 |
35 | private class MailAddress {
36 | private String mId;
37 |
38 | private MailAddress(String firstName, String lastName,
39 | String division) {
40 | this.mId = firstName.charAt(0) + "." + lastName.substring(0, 7)
41 | + "@"
42 | + division.substring(0, 5) + ".compa.ny";
43 | }
44 | }
45 | // end::buildAndSendMail[]
46 |
47 | private MailMessage formatMessage(MailFont font, String string) {
48 | return null;
49 | }
50 |
51 | private class MailMan {
52 | public void send(String mId, String subject, MailMessage mMessage) {}
53 | public void sendMail(Mail mail) {}
54 | }
55 |
56 | private class MailFont {}
57 |
58 | private class MailMessage {}
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/chartlib/v1/Charts.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.chartlib.v1;
2 |
3 | import java.awt.Graphics;
4 | import java.awt.Point;
5 |
6 | import eu.sig.training.ch05.boardpanel.v2.Rectangle;
7 |
8 | public class Charts {
9 | @SuppressWarnings("unused")
10 | // tag::drawBarChart[]
11 | public static void drawBarChart(Graphics g,
12 | CategoryItemRendererState state,
13 | Rectangle graphArea,
14 | CategoryPlot plot,
15 | CategoryAxis domainAxis,
16 | ValueAxis rangeAxis,
17 | CategoryDataset dataset) {
18 | // ..
19 | }
20 | // end::drawBarChart[]
21 |
22 | // tag::drawBarChartDefault[]
23 | public static void drawBarChart(Graphics g, CategoryDataset dataset) {
24 | Charts.drawBarChart(g,
25 | CategoryItemRendererState.DEFAULT,
26 | new Rectangle(new Point(0, 0), 100, 100),
27 | CategoryPlot.DEFAULT,
28 | CategoryAxis.DEFAULT,
29 | ValueAxis.DEFAULT,
30 | dataset);
31 | }
32 | // end::drawBarChartDefault[]
33 | }
34 |
35 | class CategoryItemRendererState {
36 | public static final CategoryItemRendererState DEFAULT = null;
37 | }
38 |
39 | class CategoryPlot {
40 | public static final CategoryPlot DEFAULT = null;
41 | }
42 |
43 | class CategoryAxis {
44 | public static final CategoryAxis DEFAULT = null;
45 | }
46 |
47 | class ValueAxis {
48 | public static final ValueAxis DEFAULT = null;
49 | }
50 |
51 | class CategoryDataset {
52 | public static final CategoryDataset DEFAULT = null;
53 | }
54 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch05/chartlib/v2/BarChart.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch05.chartlib.v2;
2 |
3 | import java.awt.Graphics;
4 | import java.awt.Point;
5 |
6 | import eu.sig.training.ch05.boardpanel.v2.Rectangle;
7 |
8 | @SuppressWarnings("unused")
9 | // tag::BarChart[]
10 | public class BarChart {
11 | private CategoryItemRendererState state = CategoryItemRendererState.DEFAULT;
12 | private Rectangle graphArea = new Rectangle(new Point(0, 0), 100, 100);
13 | private CategoryPlot plot = CategoryPlot.DEFAULT;
14 | private CategoryAxis domainAxis = CategoryAxis.DEFAULT;
15 | private ValueAxis rangeAxis = ValueAxis.DEFAULT;
16 | private CategoryDataset dataset = CategoryDataset.DEFAULT;
17 |
18 | public BarChart draw(Graphics g) {
19 | // ..
20 | return this;
21 | }
22 |
23 | public ValueAxis getRangeAxis() {
24 | return rangeAxis;
25 | }
26 |
27 | public BarChart setRangeAxis(ValueAxis rangeAxis) {
28 | this.rangeAxis = rangeAxis;
29 | return this;
30 | }
31 |
32 | // More getters and setters.
33 |
34 | // end::BarChart[]
35 |
36 | public CategoryItemRendererState getState() {
37 | return state;
38 | }
39 |
40 | public BarChart setState(CategoryItemRendererState state) {
41 | this.state = state;
42 | return this;
43 | }
44 |
45 | public Rectangle getGraphArea() {
46 | return graphArea;
47 | }
48 |
49 | public BarChart setGraphArea(Rectangle graphArea) {
50 | this.graphArea = graphArea;
51 | return this;
52 | }
53 |
54 | public CategoryPlot getPlot() {
55 | return plot;
56 | }
57 |
58 | public BarChart setPlot(CategoryPlot plot) {
59 | this.plot = plot;
60 | return this;
61 | }
62 |
63 | public CategoryAxis getDomainAxis() {
64 | return domainAxis;
65 | }
66 |
67 | public BarChart setDomainAxis(CategoryAxis domainAxis) {
68 | this.domainAxis = domainAxis;
69 | return this;
70 | }
71 |
72 | public CategoryDataset getDataset() {
73 | return dataset;
74 | }
75 |
76 | public BarChart setDataset(CategoryDataset dataset) {
77 | this.dataset = dataset;
78 | return this;
79 | }
80 |
81 | }
82 |
83 | class CategoryItemRendererState {
84 | public static final CategoryItemRendererState DEFAULT = null;
85 | }
86 |
87 | class CategoryPlot {
88 | public static final CategoryPlot DEFAULT = null;
89 | }
90 |
91 | class CategoryAxis {
92 | public static final CategoryAxis DEFAULT = null;
93 | }
94 |
95 | class ValueAxis {
96 | public static final ValueAxis DEFAULT = null;
97 | }
98 |
99 | class CategoryDataset {
100 | public static final CategoryDataset DEFAULT = null;
101 | }
102 |
103 | @SuppressWarnings("serial")
104 | class BarChartTest extends java.awt.Frame {
105 | ValueAxis myValueAxis = null;
106 | CategoryDataset myDataset = null;
107 | @SuppressWarnings("unused")
108 | // tag::showMyBarChart[]
109 | private void showMyBarChart() {
110 | Graphics g = this.getGraphics();
111 | BarChart b = new BarChart()
112 | .setRangeAxis(myValueAxis)
113 | .setDataset(myDataset)
114 | .draw(g);
115 | }
116 | // end::showMyBarChart[]
117 | }
118 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/advanceddigitalcamera/DigitalCamera.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.advanceddigitalcamera;
2 |
3 | import java.awt.Image;
4 | import java.awt.image.BufferedImage;
5 |
6 | @SuppressWarnings("unused")
7 | // tag::DigitalCamera[]
8 | public class DigitalCamera {
9 | public Image takeSnapshot() {
10 | // ...
11 | // end::DigitalCamera[]
12 | return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
13 | // tag::DigitalCamera[]
14 | }
15 |
16 | public void flashLightOn() {
17 | // ...
18 | }
19 |
20 | public void flaslLightOff() {
21 | // ...
22 | }
23 |
24 | public Image takePanoramaSnapshot() {
25 | // end::DigitalCamera[]
26 | return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
27 | // tag::DigitalCamera[]
28 | // ...
29 | }
30 |
31 | public Video record() {
32 | // ...
33 | // end::DigitalCamera[]
34 | return new Video();
35 | // tag::DigitalCamera[]
36 | }
37 |
38 | public void setTimer(int seconds) {
39 | // ...
40 | }
41 |
42 | public void zoomIn() {
43 | // ...
44 | }
45 |
46 | public void zoomOut() {
47 | // ...
48 | }
49 | }
50 | // end::DigitalCamera[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/advanceddigitalcamera/Video.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.advanceddigitalcamera;
2 |
3 | public class Video {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/digitalcamera/DigitalCamera.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.digitalcamera;
2 |
3 | import java.awt.Image;
4 | import java.awt.image.BufferedImage;
5 |
6 | // tag::DigitalCamera[]
7 | public class DigitalCamera {
8 | public Image takeSnapshot() {
9 | // ...
10 | // end::DigitalCamera[]
11 | return new BufferedImage(1920, 1080, BufferedImage.TYPE_INT_ARGB);
12 | // tag::DigitalCamera[]
13 | }
14 |
15 | public void flashLightOn() {
16 | // ...
17 | }
18 |
19 | public void flaslLightOff() {
20 | // ...
21 | }
22 | }
23 | // end::DigitalCamera[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/digitalcamera/SmartphoneApp.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.digitalcamera;
2 |
3 | import java.awt.Image;
4 |
5 | @SuppressWarnings("unused")
6 | // tag::SmartphoneApp[]
7 | public class SmartphoneApp {
8 | private static DigitalCamera camera = new DigitalCamera();
9 |
10 | public static void main(String[] args) {
11 | // ...
12 | Image image = camera.takeSnapshot();
13 | // ...
14 | }
15 | }
16 | // end::SmartphoneApp[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/simpledigitalcamera/DigitalCamera.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.simpledigitalcamera;
2 |
3 | import java.awt.Image;
4 |
5 | // tag::DigitalCamera[]
6 | public class DigitalCamera implements SimpleDigitalCamera {
7 | // ...
8 | // end::DigitalCamera[]
9 | public Image takeSnapshot() {
10 | return null;
11 | }
12 |
13 | public void flashLightOn() {}
14 |
15 | public void flashLightOff() {}
16 | // tag::DigitalCamera[]
17 | }
18 | // end::DigitalCamera[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/simpledigitalcamera/SDK.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.simpledigitalcamera;
2 |
3 | public class SDK {
4 |
5 | public static SimpleDigitalCamera getCamera() {
6 | return new DigitalCamera();
7 | }
8 |
9 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/simpledigitalcamera/SimpleDigitalCamera.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.simpledigitalcamera;
2 |
3 | import java.awt.Image;
4 |
5 | // tag::SimpleDigitalCamera[]
6 | public interface SimpleDigitalCamera {
7 | Image takeSnapshot();
8 |
9 | void flashLightOn();
10 |
11 | void flashLightOff();
12 | }
13 | // end::SimpleDigitalCamera[]
14 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/simpledigitalcamera/SmartphoneApp.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.simpledigitalcamera;
2 |
3 | import java.awt.Image;
4 |
5 | @SuppressWarnings("unused")
6 | // tag::SmartphoneApp[]
7 | public class SmartphoneApp {
8 | private static SimpleDigitalCamera camera = SDK.getCamera();
9 |
10 | public static void main(String[] args) {
11 | // ...
12 | Image image = camera.takeSnapshot();
13 | // ...
14 | }
15 | }
16 | // end::SmartphoneApp[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/NotificationType.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice;
2 |
3 | public class NotificationType {
4 |
5 | public static NotificationType fromString(@SuppressWarnings("unused") String type) {
6 | return new NotificationType();
7 | }
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/User.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice;
2 |
3 | public class User {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/UserInfo.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice;
2 |
3 | public class UserInfo {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/splitted/UserBlockService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.splitted;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import eu.sig.training.ch06.userservice.User;
7 |
8 | @SuppressWarnings("unused")
9 | // tag::UserBlockService[]
10 | public class UserBlockService {
11 | public void blockUser(User user) {
12 | // ...
13 | }
14 |
15 | public List getAllBlockedUsers() {
16 | // ...
17 | // end::UserBlockService[]
18 | return new ArrayList();
19 | // tag::UserBlockService[]
20 | }
21 | }
22 | // end::UserBlockService[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/splitted/UserNotificationService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.splitted;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import eu.sig.training.ch06.userservice.NotificationType;
7 | import eu.sig.training.ch06.userservice.User;
8 |
9 | @SuppressWarnings("unused")
10 | // tag::UserNotificationService[]
11 | public class UserNotificationService {
12 | public List getNotificationTypes(User user) {
13 | // ...
14 | // end::UserNotificationService[]
15 | return new ArrayList();
16 | // tag::UserNotificationService[]
17 | }
18 |
19 | public void register(User user, NotificationType type) {
20 | // ...
21 | }
22 |
23 | public void unregister(User user, NotificationType type) {
24 | // ...
25 | }
26 | }
27 | // end::UserNotificationService[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/splitted/UserService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.splitted;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import eu.sig.training.ch06.userservice.User;
7 | import eu.sig.training.ch06.userservice.UserInfo;
8 |
9 | @SuppressWarnings("unused")
10 | // tag::UserService[]
11 | public class UserService {
12 | public User loadUser(String userId) {
13 | // ...
14 | // end::UserService[]
15 | return new User();
16 | // tag::UserService[]
17 | }
18 |
19 | public boolean doesUserExist(String userId) {
20 | // ...
21 | // end::UserService[]
22 | return true;
23 | // tag::UserService[]
24 | }
25 |
26 | public User changeUserInfo(UserInfo userInfo) {
27 | // ...
28 | // end::UserService[]
29 | return new User();
30 | // tag::UserService[]
31 | }
32 |
33 | public List searchUsers(UserInfo userInfo) {
34 | // ...
35 | // end::UserService[]
36 | return new ArrayList();
37 | // tag::UserService[]
38 | }
39 | }
40 | // end::UserService[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/v1/UserRestAPI.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.v1;
2 |
3 | import javax.ws.rs.GET;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.PathParam;
6 | import javax.ws.rs.core.Response;
7 |
8 | import eu.sig.training.ch06.userservice.User;
9 |
10 | // tag::UserRestAPI[]
11 | // The @Path and @GET attributes are defined by the the Java REST Service API
12 | @Path("/user")
13 | public class UserRestAPI {
14 |
15 | private final UserService userService = new UserService();
16 |
17 | // ...
18 | // end::UserRestAPI[]
19 | public Response toJson(@SuppressWarnings("unused") User u) {
20 | return Response.accepted().build();
21 | }
22 | // tag::UserRestAPI[]
23 |
24 | @GET
25 | @Path("/{userId}")
26 | public Response getUser(@PathParam(value = "userId") String userId) {
27 | User user = userService.loadUser(userId);
28 | return toJson(user);
29 | }
30 | }
31 | // end::UserRestAPI[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/v1/UserService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.v1;
2 |
3 | import eu.sig.training.ch06.userservice.User;
4 | import eu.sig.training.ch06.userservice.UserInfo;
5 |
6 | @SuppressWarnings("unused")
7 | // tag::UserService[]
8 | public class UserService {
9 | public User loadUser(String userId) {
10 | // ...
11 | // end::UserService[]
12 | return new User();
13 | // tag::UserService[]
14 | }
15 |
16 | public boolean doesUserExist(String userId) {
17 | // ...
18 | // end::UserService[]
19 | return true;
20 | // tag::UserService[]
21 | }
22 |
23 | public User changeUserInfo(UserInfo userInfo) {
24 | // ...
25 | // end::UserService[]
26 | return new User();
27 | // tag::UserService[]
28 | }
29 | }
30 | // end::UserSerice[]
31 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/v2/NotificationRestAPI.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.v2;
2 |
3 | import javax.ws.rs.POST;
4 | import javax.ws.rs.Path;
5 | import javax.ws.rs.PathParam;
6 | import javax.ws.rs.core.Response;
7 |
8 | import org.apache.http.HttpStatus;
9 |
10 | import eu.sig.training.ch06.userservice.NotificationType;
11 | import eu.sig.training.ch06.userservice.User;
12 |
13 | // tag::NotificationRestAPI[]
14 | @Path("/notification")
15 | public class NotificationRestAPI {
16 | private final UserService userService = new UserService();
17 |
18 | // ...
19 | // end::NotificationRestAPI[]
20 | public Response toJson(@SuppressWarnings("unused") int status) {
21 | return Response.accepted().build();
22 | }
23 | // tag::NotificationRestAPI[]
24 |
25 | @POST
26 | @Path("/register/{userId}/{type}")
27 | public Response register(@PathParam(value = "userId") String userId,
28 | @PathParam(value = "type") String notificationType) {
29 | User user = userService.loadUser(userId);
30 | userService.registerForNotifications(user, NotificationType.fromString(notificationType));
31 | return toJson(HttpStatus.SC_OK);
32 | }
33 |
34 | @POST
35 | @Path("/unregister/{userId}/{type}")
36 | public Response unregister(@PathParam(value = "userId") String userId,
37 | @PathParam(value = "type") String notificationType) {
38 | User user = userService.loadUser(userId);
39 | userService.unregisterForNotifications(user, NotificationType.fromString(notificationType));
40 | return toJson(HttpStatus.SC_OK);
41 | }
42 | }
43 | // end::NotificationRestAPI[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/v2/UserService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.v2;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import eu.sig.training.ch06.userservice.NotificationType;
7 | import eu.sig.training.ch06.userservice.User;
8 | import eu.sig.training.ch06.userservice.UserInfo;
9 |
10 | @SuppressWarnings("unused")
11 | // tag::UserService[]
12 | public class UserService {
13 | public User loadUser(String userId) {
14 | // ...
15 | // end::UserService[]
16 | return new User();
17 | // tag::UserService[]
18 | }
19 |
20 | public boolean doesUserExist(String userId) {
21 | // ...
22 | // end::UserService[]
23 | return true;
24 | // tag::UserService[]
25 | }
26 |
27 | public User changeUserInfo(UserInfo userInfo) {
28 | // ...
29 | // end::UserService[]
30 | return new User();
31 | // tag::UserService[]
32 | }
33 |
34 | public List getNotificationTypes(User user) {
35 | // ...
36 | // end::UserService[]
37 | return new ArrayList();
38 | // tag::UserService[]
39 | }
40 |
41 | public void registerForNotifications(User user, NotificationType type) {
42 | // ...
43 | }
44 |
45 | public void unregisterForNotifications(User user, NotificationType type) {
46 | // ...
47 | }
48 | }
49 | // end::UserSerice[]
50 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch06/userservice/v3/UserService.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch06.userservice.v3;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import eu.sig.training.ch06.userservice.NotificationType;
7 | import eu.sig.training.ch06.userservice.User;
8 | import eu.sig.training.ch06.userservice.UserInfo;
9 |
10 | @SuppressWarnings("unused")
11 | // tag::UserService[]
12 | public class UserService {
13 | public User loadUser(String userId) {
14 | // ...
15 | // end::UserService[]
16 | return new User();
17 | // tag::UserService[]
18 | }
19 |
20 | public boolean doesUserExist(String userId) {
21 | // ...
22 | // end::UserService[]
23 | return true;
24 | // tag::UserService[]
25 | }
26 |
27 | public User changeUserInfo(UserInfo userInfo) {
28 | // ...
29 | // end::UserService[]
30 | return new User();
31 | // tag::UserService[]
32 | }
33 |
34 | public List getNotificationTypes(User user) {
35 | // ...
36 | // end::UserService[]
37 | return new ArrayList();
38 | // tag::UserService[]
39 | }
40 |
41 | public void registerForNotifications(User user, NotificationType type) {
42 | // ...
43 | }
44 |
45 | public void unregisterForNotifications(User user, NotificationType type) {
46 | // ...
47 | }
48 |
49 | public List searchUsers(UserInfo userInfo) {
50 | // ...
51 | // end::UserService[]
52 | return new ArrayList();
53 | // tag::UserService[]
54 | }
55 |
56 | public void blockUser(User user) {
57 | // ...
58 | }
59 |
60 | public List getAllBlockedUsers() {
61 | // ...
62 | // end::UserService[]
63 | return new ArrayList();
64 | // tag::UserService[]
65 | }
66 | }
67 | // end::UserSerice[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AWSCloudServerFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | // tag::AWSCloudServerFactory[]
4 | public class AWSCloudServerFactory implements CloudServerFactory {
5 | public CloudServer launchComputeServer() {
6 | return new AWSComputeServer();
7 | }
8 |
9 | public CloudServer launchDatabaseServer() {
10 | return new AWSDatabaseServer();
11 | }
12 |
13 | public CloudStorage createCloudStorage(long sizeGb) {
14 | return new AWSCloudStorage(sizeGb);
15 | }
16 | }
17 | // end::AWSCloudServerFactory[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AWSCloudStorage.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AWSCloudStorage implements CloudStorage {
4 |
5 | public AWSCloudStorage(@SuppressWarnings("unused") long sizeGb) {}
6 |
7 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AWSComputeServer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AWSComputeServer implements CloudServer {
4 |
5 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AWSDatabaseServer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AWSDatabaseServer implements CloudServer {
4 |
5 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/ApplicationLauncher.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | @SuppressWarnings("unused")
4 | // tag::ApplicationLauncher[]
5 | public class ApplicationLauncher {
6 |
7 | public static void main(String[] args) {
8 | CloudServerFactory factory;
9 | if (args[1].equals("-azure")) {
10 | factory = new AzureCloudServerFactory();
11 | } else {
12 | factory = new AWSCloudServerFactory();
13 | }
14 | CloudServer computeServer = factory.launchComputeServer();
15 | CloudServer databaseServer = factory.launchDatabaseServer();
16 | // end::ApplicationLauncher[]
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AzureCloudServerFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | // tag::AzureCloudServerFactory[]
4 | public class AzureCloudServerFactory implements CloudServerFactory {
5 | public CloudServer launchComputeServer() {
6 | return new AzureComputeServer();
7 | }
8 |
9 | public CloudServer launchDatabaseServer() {
10 | return new AzureDatabaseServer();
11 | }
12 |
13 | public CloudStorage createCloudStorage(long sizeGb) {
14 | return new AzureCloudStorage(sizeGb);
15 | }
16 | }
17 | // end::AzureCloudServerFactory[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AzureCloudStorage.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AzureCloudStorage implements CloudStorage {
4 | public AzureCloudStorage(@SuppressWarnings("unused") long sizeGb) {}
5 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AzureComputeServer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AzureComputeServer implements CloudServer {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/AzureDatabaseServer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public class AzureDatabaseServer implements CloudServer {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/CloudServer.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public interface CloudServer {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/CloudServerFactory.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | // tag::CloudServerFactory[]
4 | public interface CloudServerFactory {
5 | CloudServer launchComputeServer();
6 |
7 | CloudServer launchDatabaseServer();
8 |
9 | CloudStorage createCloudStorage(long sizeGb);
10 | }
11 | // end::CloudServerFactory[]
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch07/CloudStorage.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch07;
2 |
3 | public interface CloudStorage {
4 |
5 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch10/PerfectPicture.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch10;
2 |
3 | import java.awt.Image;
4 |
5 | import eu.sig.training.ch06.simpledigitalcamera.SimpleDigitalCamera;
6 |
7 | public class PerfectPicture {
8 | public static SimpleDigitalCamera camera = null;
9 |
10 | // tag::takePerfectPicture[]
11 | public final static int DAYLIGHT_START = 6;
12 |
13 | public Image takePerfectPicture(int currentHour) {
14 | Image image;
15 | if (currentHour < PerfectPicture.DAYLIGHT_START) {
16 | camera.flashLightOn();
17 | image = camera.takeSnapshot();
18 | camera.flashLightOff();
19 | } else {
20 | image = camera.takeSnapshot();
21 | }
22 | return image;
23 | }
24 | // end::takePerfectPicture[]
25 | }
26 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch10/Program.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch10;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.IOException;
5 | import java.io.InputStreamReader;
6 |
7 | import eu.sig.training.ch04.v1.Accounts;
8 |
9 | public class Program {
10 | public static void main(String[] args) throws IOException {
11 | BufferedReader isr =
12 | new BufferedReader(new InputStreamReader(System.in));
13 | String acct;
14 | do {
15 | System.out.println("Type a bank account number on the next line.");
16 | acct = isr.readLine();
17 | System.out.println("Bank account number '" + acct + "' is" +
18 | (Accounts.isValid(acct) ? "" : " not") + " valid.");
19 | } while (acct != null && acct.length() != 0);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch11/DeadCode.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch11;
2 |
3 | public class DeadCode {
4 | public class Transaction {
5 | public Transaction(@SuppressWarnings("unused") long uid) {
6 | }
7 | }
8 |
9 | @SuppressWarnings("unused")
10 | // tag::getTransaction[]
11 | public Transaction getTransaction(long uid) {
12 | Transaction result = new Transaction(uid);
13 | if (result != null) {
14 | return result;
15 | } else {
16 | return lookupTransaction(uid); // <1>
17 | }
18 | }
19 | // end::getTransaction[]
20 |
21 | private Transaction lookupTransaction(
22 | @SuppressWarnings("unused") long uid) {
23 | return null;
24 | }
25 | }
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch11/MagicConstants.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch11;
2 |
3 | public class MagicConstants {
4 |
5 | public class Customer {
6 | private final int age;
7 |
8 | public Customer(int age) {
9 | this.age = age;
10 | }
11 |
12 | public int getAge() {
13 | return age;
14 | }
15 | }
16 |
17 | public class UseMagicConstants {
18 |
19 | // tag::calculateFareMagicConstants[]
20 | float calculateFare(Customer c, long distance) {
21 | float travelledDistanceFare = distance * 0.10f;
22 | if (c.getAge() < 12) {
23 | travelledDistanceFare *= 0.25f;
24 | } else
25 | if (c.getAge() >= 65) {
26 | travelledDistanceFare *= 0.5f;
27 | }
28 | return 3.00f + travelledDistanceFare;
29 | }
30 | // end::calculateFareMagicConstants[]
31 |
32 | }
33 |
34 | public class DoNotUseMagicConstants {
35 | // tag::calculateFareDoNotUseMagicConstants[]
36 | private static final float BASE_RATE = 3.00f;
37 | private static final float FARE_PER_KM = 0.10f;
38 | private static final float DISCOUNT_RATE_CHILDREN = 0.25f;
39 | private static final float DISCOUNT_RATE_ELDERLY = 0.5f;
40 | private static final int MAXIMUM_AGE_CHILDREN = 12;
41 | private static final int MINIMUM_AGE_ELDERLY = 65;
42 |
43 | float calculateFare(Customer c, long distance) {
44 | float travelledDistanceFare = distance * FARE_PER_KM;
45 | if (c.getAge() < MAXIMUM_AGE_CHILDREN) {
46 | travelledDistanceFare *= DISCOUNT_RATE_CHILDREN;
47 | } else
48 | if (c.getAge() >= MINIMUM_AGE_ELDERLY) {
49 | travelledDistanceFare *= DISCOUNT_RATE_ELDERLY;
50 | }
51 | return BASE_RATE + travelledDistanceFare;
52 | }
53 | // end::calculateFareDoNotUseMagicConstants[]
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch11/StandardContext.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch11;
2 |
3 | public class StandardContext {
4 |
5 | @SuppressWarnings("unused")
6 | // tag::validateFilterMap[]
7 | private void validateFilterMap(FilterMap filterMap) {
8 | // Validate the proposed filter mapping
9 | String filterName = filterMap.getFilterName();
10 | String[] servletNames = filterMap.getServletNames();
11 | String[] urlPatterns = filterMap.getURLPatterns();
12 | if (findFilterDef(filterName) == null)
13 | throw new IllegalArgumentException(
14 | sm.getString("standardContext.filterMap.name", filterName));
15 |
16 | if (!filterMap.getMatchAllServletNames() &&
17 | !filterMap.getMatchAllUrlPatterns() &&
18 | (servletNames.length == 0) && (urlPatterns.length == 0))
19 | throw new IllegalArgumentException(
20 | sm.getString("standardContext.filterMap.either"));
21 | // FIXME: Older spec revisions may still check this
22 | /*
23 | if ((servletNames.length != 0) && (urlPatterns.length != 0))
24 | throw new IllegalArgumentException
25 | (sm.getString("standardContext.filterMap.either"));
26 | */
27 | for (int i = 0; i < urlPatterns.length; i++) {
28 | if (!validateURLPattern(urlPatterns[i])) {
29 | throw new IllegalArgumentException(
30 | sm.getString("standardContext.filterMap.pattern",
31 | urlPatterns[i]));
32 | }
33 | }
34 | }
35 | // end::validateFilterMap[]
36 |
37 | public class GetStringObject {
38 | public String getString(String string) {
39 | return string;
40 | }
41 |
42 | public String getString(String string,
43 | @SuppressWarnings("unused") Object o) {
44 | return string;
45 | }
46 | }
47 |
48 | private GetStringObject sm = new GetStringObject();
49 |
50 | public class FilterMap {
51 |
52 | public boolean getMatchAllUrlPatterns() {
53 | return false;
54 | }
55 |
56 | public String[] getURLPatterns() {
57 | return null;
58 | }
59 |
60 | public String[] getServletNames() {
61 | return null;
62 | }
63 |
64 | public String getFilterName() {
65 | return null;
66 | }
67 |
68 | public boolean getMatchAllServletNames() {
69 | return false;
70 | }
71 |
72 | }
73 |
74 | private boolean validateURLPattern(
75 | @SuppressWarnings("unused") String string) {
76 | return false;
77 | }
78 |
79 | private Object findFilterDef(
80 | @SuppressWarnings("unused") String filterName) {
81 | return null;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/java/eu/sig/training/ch11/ValuableVsNonValuableComments.java:
--------------------------------------------------------------------------------
1 | // This unit suggest labels for autocompletion
2 | public AutoCompletionCandidates doAutoCompleteLabels(@QueryParameter String value) {
3 | AutoCompletionCandidates result = new AutoCompletionCandidates();
4 | // show all suggestions for short strings
5 | if (query.length() < 2) {
6 | result.add(getProjectLabelsAsArray(job));
7 | } else {
8 | for (String branch : getProjectLabelsAsArray(job)) {
9 | if (branch.toLowerCase().contains(query.toLowerCase())) {
10 | result.add(branch);
11 | }
12 | }
13 | }
14 | return result;
15 | }
16 |
--------------------------------------------------------------------------------
/src/test/csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("maintainabilitybooktests")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Vagrant Inc.")]
11 | [assembly: AssemblyProduct("maintainabilitybooktests.Properties")]
12 | [assembly: AssemblyCopyright("Software Improvement Group")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("f00adb74-f9a6-4f53-8f36-2963d85c4319")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | [assembly: AssemblyVersion("1.0.*")]
32 | [assembly: AssemblyFileVersion("1.0.0.0")]
33 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch03/FlagFactoryWithMapTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 |
5 | namespace eu.sig.training.ch03
6 | {
7 | [TestFixture]
8 | public class FlagFactoryWithMapTest
9 | {
10 |
11 | [Test]
12 | public void TestGetFlagColors()
13 | {
14 | FlagFactoryWithMap factory = new FlagFactoryWithMap();
15 |
16 | IList colors = factory.GetFlagColors(Nationality.DUTCH);
17 |
18 | Assert.AreEqual(Color.Red, colors[0]);
19 | Assert.AreEqual(Color.White, colors[1]);
20 | Assert.AreEqual(Color.Blue, colors[2]);
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch03/FlagsTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 |
5 | namespace eu.sig.training.ch03
6 | {
7 | [TestFixture]
8 | public class FlagsTest
9 | {
10 |
11 | [Test]
12 | public void testGetFlag()
13 | {
14 | FlagFactory factory = new FlagFactory();
15 |
16 | IList colors = factory.GetFlagColors(Nationality.DUTCH);
17 |
18 | Assert.AreEqual(Color.Red, colors[0]);
19 | Assert.AreEqual(Color.White, colors[1]);
20 | Assert.AreEqual(Color.Blue, colors[2]);
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch03/binarytree/BinaryTreeSearchTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NUnit.Framework;
3 |
4 | namespace eu.sig.training.ch03.binarytree
5 | {
6 | [TestFixture]
7 | public class BinaryTreeSearchTest
8 | {
9 |
10 | [Test]
11 | public void testSimpleTree()
12 | {
13 | BinaryTreeNode root = new BinaryTreeNode(5);
14 | root.Insert(3);
15 | root.Insert(10);
16 | root.Insert(12);
17 |
18 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.CalculateDepth(root, 12), 2);
19 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch.CalculateDepth(root, 12), 2);
20 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch.CalculateDepth(root, 12), 2);
21 | }
22 |
23 | [Test]
24 | public void testDepth0()
25 | {
26 | BinaryTreeNode root = new BinaryTreeNode(2);
27 | root.Insert(5);
28 | root.Insert(1);
29 | root.Insert(16);
30 |
31 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.CalculateDepth(root, 2), 0);
32 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch.CalculateDepth(root, 2), 0);
33 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch.CalculateDepth(root, 2), 0);
34 | }
35 |
36 | [Test]
37 | public void testNotInTree()
38 | {
39 | BinaryTreeNode root = new BinaryTreeNode(2);
40 | root.Insert(5);
41 | root.Insert(1);
42 | root.Insert(16);
43 | bool exceptionCaught_v1 = false;
44 | bool exceptionCaught_v2 = false;
45 | bool exceptionCaught_v3 = false;
46 |
47 | #pragma warning disable 168
48 | try
49 | {
50 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.CalculateDepth(root, 17), 0);
51 | }
52 | catch (TreeException e)
53 | {
54 | exceptionCaught_v1 = true;
55 | }
56 | try
57 | {
58 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch
59 | .CalculateDepth(root, 17), 0);
60 | }
61 | catch (TreeException e)
62 | {
63 | exceptionCaught_v2 = true;
64 | }
65 | try
66 | {
67 | Assert.AreEqual(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch
68 | .CalculateDepth(root, 17), 0);
69 | }
70 | catch (TreeException e)
71 | {
72 | exceptionCaught_v3 = true;
73 | }
74 | Assert.IsTrue(exceptionCaught_v1);
75 | Assert.IsTrue(exceptionCaught_v2);
76 | Assert.IsTrue(exceptionCaught_v3);
77 | #pragma warning restore 168
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch03/withmapandtypes/FlagsTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 |
5 | namespace eu.sig.training.ch03.withmapandtypes
6 | {
7 | [TestFixture]
8 | public class FlagsTest
9 | {
10 |
11 | [Test]
12 | public void TestGetFlag()
13 | {
14 | FlagFactory factory = new FlagFactory();
15 |
16 | IList colors = factory.GetFlagColors(Nationality.DUTCH);
17 |
18 | Assert.AreEqual(Color.Red, colors[0]);
19 | Assert.AreEqual(Color.White, colors[1]);
20 | Assert.AreEqual(Color.Blue, colors[2]);
21 | }
22 |
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch04/v1/AccountsTest.cs:
--------------------------------------------------------------------------------
1 | // tag::AccountsTest[]
2 | using NUnit.Framework;
3 |
4 | namespace eu.sig.training.ch04.v1
5 | {
6 | [TestFixture]
7 | public class AccountsTest
8 | {
9 | [Test]
10 | public void TestIsValidNormalCases()
11 | {
12 | Assert.IsTrue(Accounts.IsValid("123456789"));
13 | Assert.IsFalse(Accounts.IsValid("123456788"));
14 | }
15 |
16 | // end::AccountsTest[]
17 |
18 | // This test is meant to fail.
19 | [Ignore("Deliberately fails for illustration purpose")]
20 | // tag::testEmptyString[]
21 | [Test]
22 | public void TestEmptyString()
23 | {
24 | Assert.IsFalse(Accounts.IsValid(""));
25 | }
26 | // end::testEmptyString[]
27 |
28 | #pragma warning disable 219
29 | // This test is meant to fail, that's why we ignore it.
30 | [Ignore("Deliberately fails for illustration purpose")]
31 | // tag::showError[]
32 | [Test]
33 | public void ShowError()
34 | {
35 | int tmp = 0, dummy = 1 / tmp;
36 | // Next line is never executed because the previous one raises an
37 | // exception.
38 | // If it were executed, you'll never see the assert message because
39 | // the test always succeeds.
40 | Assert.IsTrue(true);
41 | }
42 | // end::showError[]
43 | #pragma warning restore 219
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch04/v3/CheckingAccountTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace eu.sig.training.ch04.v3
4 | {
5 |
6 | [TestFixture]
7 | public class CheckingsAccountTest
8 | {
9 |
10 | CheckingAccount myAccount;
11 | CheckingAccount counterAccount;
12 |
13 | [SetUp]
14 | public void Init()
15 | {
16 | myAccount = Accounts.MakeAccount("123456789");
17 | counterAccount = Accounts.MakeAccount("497164833");
18 | }
19 |
20 | [Test]
21 | [ExpectedException(typeof(BusinessException))]
22 | public void TestTransferLimit()
23 | {
24 | myAccount.MakeTransfer(Accounts.GetAccountNumber(counterAccount), new Money());
25 | }
26 | }
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch04/v3/SavingsAccountTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace eu.sig.training.ch04.v3
4 | {
5 |
6 | [TestFixture]
7 | public class SavingsAccountTest
8 | {
9 |
10 | SavingsAccount myAccount;
11 | CheckingAccount registeredCounterAccount;
12 |
13 | [SetUp]
14 | public void Init()
15 | {
16 | myAccount = Accounts.MakeAccount("123456789");
17 | registeredCounterAccount = Accounts.MakeAccount("497164833");
18 | myAccount.RegisteredCounterAccount = registeredCounterAccount;
19 | }
20 |
21 | [Test]
22 | public void TestCounterAccount()
23 | {
24 | myAccount.MakeTransfer("497164833", new Money());
25 | }
26 |
27 | [Test]
28 | [ExpectedException(typeof(BusinessException))]
29 | public void TestNoCounterAccount()
30 | {
31 | CheckingAccount unRegisteredCounterAccount = Accounts.MakeAccount("1439");
32 | myAccount.MakeTransfer(Accounts.GetAccountNumber(unRegisteredCounterAccount), new Money());
33 | }
34 |
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch04/v4/AccountsTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 |
3 | namespace eu.sig.training.ch04.v4
4 | {
5 | [TestFixture]
6 | public class AccountsTest
7 | {
8 |
9 | [Test]
10 | public void TestIsValidNormalCases()
11 | {
12 | Assert.IsTrue(Accounts.IsValid("123456789"));
13 | Assert.IsFalse(Accounts.IsValid("123456788"));
14 | }
15 |
16 | [Test]
17 | public void TestIsValidLetters()
18 | {
19 | Assert.IsFalse(Accounts.IsValid("ABCDEFGHK"));
20 | }
21 |
22 | [Test]
23 | public void TestIsValidNonNormal()
24 | {
25 | Assert.IsFalse(Accounts.IsValid(""));
26 | }
27 |
28 | [Test]
29 | public void TestIsValidNonNumeric()
30 | {
31 | Assert.IsFalse(Accounts.IsValid("12.34.56."));
32 | }
33 |
34 | [Test]
35 | public void TestIsValidToolong()
36 | {
37 | Assert.IsFalse(Accounts.IsValid("1234567890"));
38 | }
39 |
40 | [Test]
41 | public void TestIsValidTooshort()
42 | {
43 | Assert.IsFalse(Accounts.IsValid("12345677"));
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch06/userservice/v1/UserControllerTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Http;
3 | using System.Web.Http.Results;
4 | using NUnit.Framework;
5 |
6 | using eu.sig.training.ch06.userservice;
7 |
8 | namespace eu.sig.training.ch06.userservice.v1
9 | {
10 | [TestFixture]
11 | class UserControllerTest
12 | {
13 | [Test]
14 | public void TestGetUserById()
15 | {
16 | UserController controller = new UserController();
17 | IHttpActionResult action = controller.GetUserById("user@example.com");
18 | var result = action as OkNegotiatedContentResult;
19 | Assert.AreEqual("user@example.com", result.Content.Id);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch06/userservice/v2/NotificationControllerTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Http;
3 | using System.Web.Http.Results;
4 | using NUnit.Framework;
5 |
6 | using eu.sig.training.ch06.userservice;
7 |
8 | namespace eu.sig.training.ch06.userservice.v2
9 | {
10 | [TestFixture]
11 | class NotificationControllerTest
12 | {
13 | private NotificationController controller;
14 |
15 | [SetUp]
16 | public void SetUp()
17 | {
18 | NotificationController controller = new NotificationController();
19 | }
20 |
21 | [Test]
22 | public void TestRegister()
23 | {
24 | IHttpActionResult action = controller.Register("user@example.com", "");
25 | var result = action as OkNegotiatedContentResult;
26 | Assert.AreEqual("user@example.com", result.Content.Name);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch10/PerfectPictureMockTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Drawing;
3 | using eu.sig.training.ch06.simpledigitalcamera;
4 | using Moq;
5 |
6 | namespace eu.sig.training.ch10
7 | {
8 | [TestFixture]
9 | public class PerfectPictureMoqTest
10 | {
11 | // tag::testNightPictureMockito[]
12 | [Test]
13 | public void TestNightPictureMoq()
14 | {
15 | Image image =
16 | Image.FromFile("../../../../test/resources/VanGoghStarryNight.jpg");
17 | var cameraMock = new Mock();
18 | cameraMock.Setup(foo => foo.TakeSnapshot()).Returns(image);
19 | PerfectPicture.camera = cameraMock.Object;
20 | Assert.AreSame(image, new PerfectPicture().TakePerfectPicture(0));
21 | cameraMock.Verify(foo => foo.FlashLightOn(), Times.AtMostOnce());
22 | }
23 | // end::testNightPictureMockito[]
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/csharp/eu/sig/training/ch10/PerfectPictureTest.cs:
--------------------------------------------------------------------------------
1 | using NUnit.Framework;
2 | using System.Drawing;
3 | using eu.sig.training.ch06.simpledigitalcamera;
4 |
5 | namespace eu.sig.training.ch10
6 | {
7 |
8 | [TestFixture]
9 | public class PerfectPictureTest
10 | {
11 |
12 | // tag::testDayPicture[]
13 | [Test]
14 | public void TestDayPicture()
15 | {
16 | Image image =
17 | Image.FromFile("../../../../test/resources/VanGoghSunflowers.jpg");
18 | DigitalCameraStub cameraStub = new DigitalCameraStub();
19 | cameraStub.TestImage = image;
20 | PerfectPicture.camera = cameraStub;
21 | Assert.AreSame(image, new PerfectPicture().TakePerfectPicture(12));
22 | }
23 | // end::testDayPicture[]
24 |
25 | // tag::testNightPicture[]
26 | [Test]
27 | public void TestNightPicture()
28 | {
29 | Image image =
30 | Image.FromFile("../../../../test/resources/VanGoghStarryNight.jpg");
31 | DigitalCameraMock cameraMock = new DigitalCameraMock();
32 | cameraMock.TestImage = image;
33 | PerfectPicture.camera = cameraMock;
34 | Assert.AreSame(image, new PerfectPicture().TakePerfectPicture(0));
35 | Assert.AreEqual(1, cameraMock.FlashOnCounter);
36 | }
37 | // end::testNightPicture[]
38 |
39 | }
40 |
41 | // tag::DigitalCameraStub[]
42 | class DigitalCameraStub : ISimpleDigitalCamera
43 | {
44 | public Image TestImage;
45 |
46 | public Image TakeSnapshot()
47 | {
48 | return this.TestImage;
49 | }
50 |
51 | public void FlashLightOn()
52 | {
53 | }
54 |
55 | public void FlashLightOff()
56 | {
57 | }
58 | }
59 | // end::DigitalCameraStub[]
60 |
61 | // tag::DigitalCameraMock[]
62 | class DigitalCameraMock : ISimpleDigitalCamera
63 | {
64 | public Image TestImage;
65 | public int FlashOnCounter = 0;
66 |
67 | public Image TakeSnapshot()
68 | {
69 | return this.TestImage;
70 | }
71 |
72 | public void FlashLightOn()
73 | {
74 | this.FlashOnCounter++;
75 | }
76 |
77 | public void FlashLightOff()
78 | {
79 | }
80 | }
81 | // end::DigitalCameraMock[]
82 | }
83 |
--------------------------------------------------------------------------------
/src/test/csharp/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch03/FlagFactoryWithMapTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.awt.Color;
6 | import java.util.List;
7 |
8 | import org.junit.Test;
9 |
10 | public class FlagFactoryWithMapTest {
11 |
12 | @Test
13 | public void testGetFlagColors() {
14 | FlagFactoryWithMap factory = new FlagFactoryWithMap();
15 |
16 | List colors = factory.getFlagColors(Nationality.DUTCH);
17 |
18 | assertEquals(Color.RED, colors.get(0));
19 | assertEquals(Color.WHITE, colors.get(1));
20 | assertEquals(Color.BLUE, colors.get(2));
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch03/FlagsTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.awt.Color;
6 | import java.util.List;
7 |
8 | import org.junit.Test;
9 |
10 | public class FlagsTest {
11 |
12 | @Test
13 | public void testGetFlag() {
14 | FlagFactory factory = new FlagFactory();
15 |
16 | List colors = factory.getFlagColors(Nationality.DUTCH);
17 |
18 | assertEquals(Color.RED, colors.get(0));
19 | assertEquals(Color.WHITE, colors.get(1));
20 | assertEquals(Color.BLUE, colors.get(2));
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch03/binarytree/BinaryTreeSearchTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch03.binarytree;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertTrue;
5 |
6 | import org.junit.Test;
7 |
8 | public class BinaryTreeSearchTest {
9 |
10 | @Test
11 | public void testSimpleTree() {
12 | BinaryTreeNode root = new BinaryTreeNode(5);
13 | root.insert(3);
14 | root.insert(10);
15 | root.insert(12);
16 |
17 | assertEquals(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.calculateDepth(root, 12), 2);
18 | assertEquals(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch.calculateDepth(root, 12), 2);
19 | assertEquals(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch.calculateDepth(root, 12), 2);
20 | }
21 |
22 | @Test
23 | public void testDepth0() {
24 | BinaryTreeNode root = new BinaryTreeNode(2);
25 | root.insert(5);
26 | root.insert(1);
27 | root.insert(16);
28 |
29 | assertEquals(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.calculateDepth(root, 2), 0);
30 | assertEquals(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch.calculateDepth(root, 2), 0);
31 | assertEquals(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch.calculateDepth(root, 2), 0);
32 | }
33 |
34 | @Test
35 | public void testNotInTree() {
36 | BinaryTreeNode root = new BinaryTreeNode(2);
37 | root.insert(5);
38 | root.insert(1);
39 | root.insert(16);
40 | boolean exceptionCaught_v1 = false;
41 | boolean exceptionCaught_v2 = false;
42 | boolean exceptionCaught_v3 = false;
43 |
44 | try {
45 | assertEquals(eu.sig.training.ch03.binarytree.v1.BinaryTreeSearch.calculateDepth(root, 17), 0);
46 | } catch (TreeException e) {
47 | exceptionCaught_v1 = true;
48 | }
49 | try {
50 | assertEquals(eu.sig.training.ch03.binarytree.v2.BinaryTreeSearch
51 | .calculateDepth(root, 17), 0);
52 | } catch (TreeException e) {
53 | exceptionCaught_v2 = true;
54 | }
55 | try {
56 | assertEquals(eu.sig.training.ch03.binarytree.v3.BinaryTreeSearch
57 | .calculateDepth(root, 17), 0);
58 | } catch (TreeException e) {
59 | exceptionCaught_v3 = true;
60 | }
61 | assertTrue(exceptionCaught_v1);
62 | assertTrue(exceptionCaught_v2);
63 | assertTrue(exceptionCaught_v3);
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch04/v1/AccountsTest.java:
--------------------------------------------------------------------------------
1 | // tag::AccountsTest[]
2 | package eu.sig.training.ch04.v1;
3 |
4 | import static org.junit.Assert.assertFalse;
5 | import static org.junit.Assert.assertTrue;
6 |
7 | import org.junit.Ignore;
8 | import org.junit.Test;
9 |
10 | public class AccountsTest {
11 |
12 | @Test
13 | public void testIsValidNormalCases() {
14 | assertTrue(Accounts.isValid("123456789"));
15 | assertFalse(Accounts.isValid("123456788"));
16 | }
17 |
18 | // end::AccountsTest[]
19 |
20 | @Ignore("Deliberately fails for illustration purpose")
21 | // tag::testEmptyString[]
22 | @Test
23 | public void testEmptyString() {
24 | assertFalse(Accounts.isValid(""));
25 | }
26 | // end::testEmptyString[]
27 |
28 | @SuppressWarnings("unused")
29 | @Ignore("Deliberately fails for illustration purpose")
30 | // tag::showError[]
31 | @Test
32 | public void showError() {
33 | int dummy = 1 / 0;
34 | // Next line is never executed because the previous one raises an
35 | // exception.
36 | // If it were executed, you'll never see the assert message because
37 | // the test always succeeds.
38 | assertTrue("You will never see this text.", true);
39 | }
40 | // end::showError[]
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch04/v3/CheckingAccountTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | import eu.sig.training.ch04.BusinessException;
7 | import eu.sig.training.ch04.Money;
8 |
9 | public class CheckingAccountTest {
10 |
11 | CheckingAccount myAccount;
12 | CheckingAccount counterAccount;
13 |
14 | @Before
15 | public void setUp() {
16 | myAccount = Accounts.makeAccount(CheckingAccount.class, "123456789");
17 | counterAccount =
18 | Accounts.makeAccount(CheckingAccount.class, "497164833");
19 | }
20 |
21 | @Test(expected = BusinessException.class)
22 | public void TestTransferLimit() throws BusinessException {
23 | myAccount.makeTransfer(Accounts.getAccountNumber(counterAccount),
24 | new Money());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch04/v3/SavingsAccountTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v3;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | import eu.sig.training.ch04.BusinessException;
7 | import eu.sig.training.ch04.Money;
8 |
9 | public class SavingsAccountTest {
10 |
11 | SavingsAccount myAccount;
12 | CheckingAccount registeredCounterAccount;
13 |
14 | @Before
15 | public void setUp() {
16 | myAccount = Accounts.makeAccount(SavingsAccount.class, "123456789");
17 | registeredCounterAccount =
18 | Accounts.makeAccount(CheckingAccount.class, "497164833");
19 | myAccount.registeredCounterAccount = registeredCounterAccount;
20 | }
21 |
22 | @Test
23 | public void testCounterAccount() throws BusinessException {
24 | myAccount.makeTransfer("497164833", new Money());
25 | }
26 |
27 | @Test(expected = BusinessException.class)
28 | public void testNoCounterAccount() throws BusinessException {
29 | CheckingAccount unRegisteredCounterAccount =
30 | Accounts.makeAccount(CheckingAccount.class, "1439");
31 | myAccount.makeTransfer(
32 | Accounts.getAccountNumber(unRegisteredCounterAccount), new Money());
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch04/v4/AccountsTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch04.v4;
2 |
3 | import static org.junit.Assert.assertFalse;
4 | import static org.junit.Assert.assertTrue;
5 |
6 | import org.junit.Test;
7 |
8 | public class AccountsTest {
9 |
10 | @Test
11 | public void testIsValidNormalCases() {
12 | assertTrue("isValid(\"123456789\") should return true",
13 | Accounts.isValid("123456789"));
14 | assertFalse("isValid(\"123456788\") should return false",
15 | Accounts.isValid("123456788"));
16 | }
17 |
18 | @Test
19 | public void testIsValidLetters() {
20 | assertFalse("isValid(\"abcdefghi\") should return false",
21 | Accounts.isValid("ABCDEFGHK"));
22 | }
23 |
24 | @Test
25 | public void testIsValidNonNormal() {
26 | assertFalse("Empty string is not a valid number", Accounts.isValid(""));
27 | }
28 |
29 | @Test
30 | public void testIsValidNonNumeric() {
31 | assertFalse("Non-numerics always invalid",
32 | Accounts.isValid("12.34.56."));
33 | }
34 |
35 | @Test
36 | public void testIsValidToolong() {
37 | assertFalse("More than 9 digits is always invalid",
38 | Accounts.isValid("1234567890"));
39 | }
40 |
41 | @Test
42 | public void testIsValidTooshort() {
43 | assertFalse("Less than 9 digits is always invalid",
44 | Accounts.isValid("12345677"));
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch10/PerfectPictureMockTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch10;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.mockito.Mockito.mock;
5 | import static org.mockito.Mockito.verify;
6 | import static org.mockito.Mockito.when;
7 |
8 | import java.awt.image.BufferedImage;
9 | import java.io.File;
10 | import java.io.IOException;
11 |
12 | import javax.imageio.ImageIO;
13 |
14 | import org.junit.Test;
15 |
16 | import eu.sig.training.ch06.simpledigitalcamera.SimpleDigitalCamera;
17 | import eu.sig.training.ch10.PerfectPicture;
18 |
19 | public class PerfectPictureMockTest {
20 | // tag::testNightPictureMockito[]
21 | @Test
22 | public void testNightPictureMockito() throws IOException {
23 | BufferedImage image =
24 | ImageIO.read(new File("src/test/resources/VanGoghStarryNight.jpg"));
25 | SimpleDigitalCamera cameraMock = mock(SimpleDigitalCamera.class);
26 | PerfectPicture.camera = cameraMock;
27 | when(cameraMock.takeSnapshot()).thenReturn(image);
28 | assertEquals(image, new PerfectPicture().takePerfectPicture(0));
29 | verify(cameraMock).flashLightOn();
30 | }
31 | // end::testNightPictureMockito[]
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/java/eu/sig/training/ch10/PerfectPictureTest.java:
--------------------------------------------------------------------------------
1 | package eu.sig.training.ch10;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.awt.Image;
6 | import java.awt.image.BufferedImage;
7 | import java.io.File;
8 | import java.io.IOException;
9 |
10 | import javax.imageio.ImageIO;
11 |
12 | import org.junit.Test;
13 |
14 | import eu.sig.training.ch06.simpledigitalcamera.SimpleDigitalCamera;
15 | import eu.sig.training.ch10.PerfectPicture;
16 |
17 | public class PerfectPictureTest {
18 |
19 | // tag::testDayPicture[]
20 | @Test
21 | public void testDayPicture() throws IOException {
22 | BufferedImage image =
23 | ImageIO.read(new File("src/test/resources/VanGoghSunflowers.jpg"));
24 | DigitalCameraStub cameraStub = new DigitalCameraStub();
25 | cameraStub.testImage = image;
26 | PerfectPicture.camera = cameraStub;
27 | assertEquals(image, new PerfectPicture().takePerfectPicture(12));
28 | }
29 | // end::testDayPicture[]
30 |
31 | // tag::testNightPicture[]
32 | @Test
33 | public void testNightPicture() throws IOException {
34 | BufferedImage image =
35 | ImageIO.read(new File("src/test/resources/VanGoghStarryNight.jpg"));
36 | DigitalCameraMock cameraMock = new DigitalCameraMock();
37 | cameraMock.testImage = image;
38 | PerfectPicture.camera = cameraMock;
39 | assertEquals(image, new PerfectPicture().takePerfectPicture(0));
40 | assertEquals(1, cameraMock.flashOnCounter);
41 | }
42 | // end::testNightPicture[]
43 |
44 | }
45 |
46 | // tag::DigitalCameraStub[]
47 | class DigitalCameraStub implements SimpleDigitalCamera {
48 | public Image testImage;
49 |
50 | public Image takeSnapshot() {
51 | return this.testImage;
52 | }
53 |
54 | public void flashLightOn() {}
55 |
56 | public void flashLightOff() {}
57 | }
58 | // end::DigitalCameraStub[]
59 |
60 | // tag::DigitalCameraMock[]
61 | class DigitalCameraMock implements SimpleDigitalCamera {
62 | public Image testImage;
63 | public int flashOnCounter = 0;
64 |
65 | public Image takeSnapshot() {
66 | return this.testImage;
67 | }
68 |
69 | public void flashLightOn() {
70 | this.flashOnCounter++;
71 | }
72 |
73 | public void flashLightOff() {}
74 | }
75 | // end::DigitalCameraMock[]
76 |
--------------------------------------------------------------------------------
/src/test/resources/VanGoghStarryNight.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/building_maintainable_software/4b67955ffcea790abb0a73c0a9c75153d210e51f/src/test/resources/VanGoghStarryNight.jpg
--------------------------------------------------------------------------------
/src/test/resources/VanGoghSunflowers.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oreillymedia/building_maintainable_software/4b67955ffcea790abb0a73c0a9c75153d210e51f/src/test/resources/VanGoghSunflowers.jpg
--------------------------------------------------------------------------------