14. public class Order
{
private int _id;
private int _userId;
private Product[] _products;
public int getId() {
return this._id;
}
public void setId(int id) {
this._id = id;
}
public int getUserId() {
return this._userId;
}
public void setUserId(int userId) {
this._userId = userId;
}
15. public Product[] getProducts() {
return this._products;
}
public void addProduct(Product product) {
this._products.add(product);
}
public void setProducts(Product[] products) {
this._products = products;
}
16. private DBConnection _db;
public Order()
{
// Read from configuration to get connection string.
string connectionString = string.Empty;
Handle fileHandle = fopen("/etc/database/app.config", "r");
while (string row = readLine(fileHandle)) {
if (row.StartsWith("dbo")) {
connectionString = row;
}
}
fclose(fileHandle);
this._db = new DBConnection(connectionString);
}
17. public static Order CreateOrder(int userId, Product[] products)
{
Order order = new Order();
order.setUserId(userId);
order.setProducts(products);
return order;
}
public static Order getOrderById(int orderId)
{
if (orderId == null || orderId < 0)
{
DBCommand command = this._db.exec("SELECT * FROM orders");
Order[] results = this._db.getResults(command);
// Get the first result.
return results[0];
}
DBCommand command = this._db.exec("SELECT * FROM orders WHERE id
= ?", orderId);
Order order = this._db.getSingle($command);
return order;
}
18. public void deliverOrder()
{
try {
WebServiceConnection networkConnection =
new WebServiceConnection("http://shpt1/shipctrl.svc");
networkConnection->open();
ShippingManager shippingManager =
new ShippingManager(networkConnection);
shippingManager.setOrder(this);
shippingManager.setDeliveryType(DeliveryType.EXPRESS);
shippingManager.shipViaWebService();
this.notifyCustomer();
} catch (Exception e) {
Handle logFile = fopen("/tmp/logfile.log", "a");
fwrite("An error occurred while delivering the order.", logFile);
fclose(logFile);
}
}
19. public void notifyCustomer()
{
try {
mailer = new Mailer();
mailer.setFrom(“orders@chrisweldon.net”, “Grumpy Baby Orders”);
mailer.setSubject(“Order #” + this.getId() + “ out for
Delivery”);
mailer.setBodyText(“Your order is being shipped!”);
mailer.send();
} catch (Exception $e) {
Handle logFile = fopen("/tmp/logfile.log", "a");
fwrite("An error occurred while emailing the notice.", logFile);
fclose(logFile);
}
}
}
30. public class DrillBitActivator {
public void ActivateDrillBit(string customerOption) {
// ...
}
}
public class DrillBitConfigurableActivator : DrillBitActivator {
public DrillBitConfigurableActivator(string freqency, Options options) {
// Configurable!
}
public override function ActivateDrillBit(string customerOption) {
// ...
}
}
31. public function ActivateDrillBit(string customerOption)
IDrillBit .drillBit = DrillBitFactory::CreateDrillBit(customerOption);
drillBit.activate(this._freq, this._options);
}
34. public class GoodManager : IManageCustomers {
public void TakeSpecifications(Specs specs) {
this.ReviewSpecifications(specs);
}
public void ReviewSpecifications(Specs specs) {
// If specs seem good.
this.GiveToEngineers(specs);
}
public void GiveToEngineers(Specs specs) {
// E-mails specs to engineers.
}
public void DealWithTheGoshDarnCustomers() {
// You better believe he does.
}
public bool IsPeoplePerson() {
return true; // Absolutely!
}
}
35.
36. public class Tom : IManageCustomers {
public void TakeSpecifications(Specs specs) {
throw new DelegateToSecretary();
}
public void ReviewSpecifications(Specs specs) {
throw new DelegateToSecretary();
}
public void GiveToEngineers(Specs specs) {
throw new DelegateToSecretary();
}
public void DealWithTheGoshDarnCustomers() {
// Your gosh darn right I do!
}
public bool IsPeoplePerson() {
return true; // I AM a people person, dammit!
}
}
37.
38. public interface ITakeSpecifications {
function TakeSpecifications(Specs specs);
}
public interface IReviewSpecifications {
function ReviewSpecifications(Specs specs);
}
public interface IGiveToEngineers {
function GiveToEngineers(Specs specs);
}
public interface IManageCustomers {
function DealWithTheGoshDarnCustomers();
function IsPeoplePerson();
}
39. public class GoodManager :
IManageCustomers, ITakeSpecifications, IReviewSpecifications, IGiveToEngineers
{
public void TakeSpecifications(Specs specs) {
this.ReviewSpecifications(specs);
}
public void ReviewSpecifications(Specs specs) {
// If specs seem good.
this.GiveToEngineers(specs);
}
public void GiveToEngineers(Specs $specs) {
// E-mails specs to engineers.
}
public void DealWithTheGoshDarnCustomers() {
// You better believe he does.
}
public bool IsPeoplePerson() {
return true; // Absolutely!
}
}
40. public class Tom : IManageCustomers {
public void DealWithTheGoshDarnCustomers() {
// Your gosh darn right I do!
}
public bool IsPeoplePerson() {
return true; // I AM a people person, dammit!
}
}
56. public class Authenticator {
private DataAccessLayer _repository;
public DataAccessLayer() {
this._repository = new DataAccessLayer();
}
public bool authenticate(string username, string password) {
string hashedPassword = md5(password);
User user = this._repository.findByUsernameAndPassword(
username, hashedPassword);
return user == null;
}
}
61. class Authenticator {
private DataAccessLayer _repository;
public Authenticator(DataAccessLayer repository) {
this._repository = repository;
}
public bool authenticate(string username, string password) {
string hashedPassword = md5(password);
User user = this._repository.findByUsernameAndPassword(
username, hashedPassword);
return user == null;
}
}
62. Dependency Inversion
• “High-level modules should not depend upon low level modules. They
should depend upon abstractions.
• “Abstractions should not depend upon details. Details should depend
upon abstractions.”
Robert Martin
64. public interface IUserRepository {
User findByUsernameAndPassword(string username, string password);
}
public class DataAccessLayer : IUserRepository {
public User findByUsernameAndPassword(string username, string password) {
// Do some database stuff.
}
}
65. class Authenticator {
private IUserRepository _repository;
public Authenticator(IUserRepository repository) {
this._repository = repository;
}
public bool authenticate(string username, string password) {
string hashedPassword = md5(password);
User user = this._repository.findByUsernameAndPassword(
username, hashedPassword);
return user == null;
}
}
70. Benefit: Flexibility
public class WebServiceUserRepository : IUserRepository {
public User findByUsernameAndPassword(string username, string password) {
// Fetch our user through JSON or SOAP
}
}
public class OAuthRepository : IUserRepository {
public User findByUsernameAndPassword(string username, string password) {
// Connect to your favorite OAuth provider
}
}