This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//-------------------------------------------------------------------------------------- | |
// 7. SOLID | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// 7.1 Single Responsibility | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// Bad | |
class UserSettings | |
{ | |
private User User; | |
public UserSettings(User user) | |
{ | |
User = user; | |
} | |
public void ChangeSettings(Settings settings) | |
{ | |
if (verifyCredentials()) | |
{ | |
// ... | |
} | |
} | |
private bool VerifyCredentials() | |
{ | |
// ... | |
} | |
} | |
// Good | |
class UserAuth | |
{ | |
private User User; | |
public UserAuth(User user) | |
{ | |
User = user; | |
} | |
public bool VerifyCredentials() | |
{ | |
// ... | |
} | |
} | |
class UserSettings | |
{ | |
private User User; | |
private UserAuth Auth; | |
public UserSettings(User user) | |
{ | |
User = user; | |
Auth = new UserAuth(user); | |
} | |
public void ChangeSettings(Settings settings) | |
{ | |
if (Auth.VerifyCredentials()) | |
{ | |
// ... | |
} | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// 7.2 Open Closed | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// Bad | |
abstract class AdapterBase | |
{ | |
protected string Name; | |
public string GetName() | |
{ | |
return Name; | |
} | |
} | |
class AjaxAdapter : AdapterBase | |
{ | |
public AjaxAdapter() | |
{ | |
Name = "ajaxAdapter"; | |
} | |
} | |
class NodeAdapter : AdapterBase | |
{ | |
public NodeAdapter() | |
{ | |
Name = "nodeAdapter"; | |
} | |
} | |
class HttpRequester : AdapterBase | |
{ | |
private readonly AdapterBase Adapter; | |
public HttpRequester(AdapterBase adapter) | |
{ | |
Adapter = adapter; | |
} | |
public bool Fetch(string url) | |
{ | |
var adapterName = Adapter.GetName(); | |
if (adapterName == "ajaxAdapter") | |
{ | |
return MakeAjaxCall(url); | |
} | |
else if (adapterName == "httpNodeAdapter") | |
{ | |
return MakeHttpCall(url); | |
} | |
} | |
private bool MakeAjaxCall(string url) | |
{ | |
// request and return promise | |
} | |
private bool MakeHttpCall(string url) | |
{ | |
// request and return promise | |
} | |
} | |
// Good | |
interface IAdapter | |
{ | |
bool Request(string url); | |
} | |
class AjaxAdapter : IAdapter | |
{ | |
public bool Request(string url) | |
{ | |
// request and return promise | |
} | |
} | |
class NodeAdapter : IAdapter | |
{ | |
public bool Request(string url) | |
{ | |
// request and return promise | |
} | |
} | |
class HttpRequester | |
{ | |
private readonly IAdapter Adapter; | |
public HttpRequester(IAdapter adapter) | |
{ | |
Adapter = adapter; | |
} | |
public bool Fetch(string url) | |
{ | |
return Adapter.Request(url); | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// 7.3 Liskov Substitution | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// Bad | |
class Rectangle | |
{ | |
protected double Width = 0; | |
protected double Height = 0; | |
public Drawable Render(double area) | |
{ | |
// ... | |
} | |
public void SetWidth(double width) | |
{ | |
Width = width; | |
} | |
public void SetHeight(double height) | |
{ | |
Height = height; | |
} | |
public double GetArea() | |
{ | |
return Width * Height; | |
} | |
} | |
class Square : Rectangle | |
{ | |
public double SetWidth(double width) | |
{ | |
Width = Height = width; | |
} | |
public double SetHeight(double height) | |
{ | |
Width = Height = height; | |
} | |
} | |
Drawable RenderLargeRectangles(Rectangle rectangles) | |
{ | |
foreach (rectangle in rectangles) | |
{ | |
rectangle.SetWidth(4); | |
rectangle.SetHeight(5); | |
var area = rectangle.GetArea(); // BAD: Will return 25 for Square. Should be 20. | |
rectangle.Render(area); | |
} | |
} | |
var rectangles = new[] { new Rectangle(), new Rectangle(), new Square() }; | |
RenderLargeRectangles(rectangles); | |
// Good | |
abstract class ShapeBase | |
{ | |
protected double Width = 0; | |
protected double Height = 0; | |
abstract public double GetArea(); | |
public Drawable Render(double area) | |
{ | |
// ... | |
} | |
} | |
class Rectangle : ShapeBase | |
{ | |
public void SetWidth(double width) | |
{ | |
Width = width; | |
} | |
public void SetHeight(double height) | |
{ | |
Height = height; | |
} | |
public double GetArea() | |
{ | |
return Width * Height; | |
} | |
} | |
class Square : ShapeBase | |
{ | |
private double Length = 0; | |
public double SetLength(double length) | |
{ | |
Length = length; | |
} | |
public double GetArea() | |
{ | |
return Math.Pow(Length, 2); | |
} | |
} | |
Drawable RenderLargeRectangles(Rectangle rectangles) | |
{ | |
foreach (rectangle in rectangles) | |
{ | |
if (rectangle is Square) | |
{ | |
rectangle.SetLength(5); | |
} | |
else if (rectangle is Rectangle) | |
{ | |
rectangle.SetWidth(4); | |
rectangle.SetHeight(5); | |
} | |
var area = rectangle.GetArea(); | |
rectangle.Render(area); | |
} | |
} | |
var shapes = new[] { new Rectangle(), new Rectangle(), new Square() }; | |
RenderLargeRectangles(shapes); | |
//-------------------------------------------------------------------------------------- | |
// 7.4 Interface Segregation | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// Bad | |
public interface IEmployee | |
{ | |
void Work(); | |
void Eat(); | |
} | |
public class Human : IEmployee | |
{ | |
public void Work() | |
{ | |
// ....working | |
} | |
public void Eat() | |
{ | |
// ...... eating in lunch break | |
} | |
} | |
public class Robot : IEmployee | |
{ | |
public void Work() | |
{ | |
//.... working much more | |
} | |
public void Eat() | |
{ | |
//.... robot can't eat, but it must implement this method | |
} | |
} | |
// Good | |
public interface IWorkable | |
{ | |
void Work(); | |
} | |
public interface IFeedable | |
{ | |
void Eat(); | |
} | |
public interface IEmployee : IFeedable, IWorkable | |
{ | |
} | |
public class Human : IEmployee | |
{ | |
public void Work() | |
{ | |
// ....working | |
} | |
public void Eat() | |
{ | |
//.... eating in lunch break | |
} | |
} | |
// robot can only work | |
public class Robot : IWorkable | |
{ | |
public void Work() | |
{ | |
// ....working | |
} | |
} | |
//-------------------------------------------------------------------------------------- | |
// 7.4 Dependency Inversion | |
//-------------------------------------------------------------------------------------- | |
//-------------------------------------------------------------------------------------- | |
// Bad | |
public abstract class EmployeeBase | |
{ | |
protected virtual void Work() | |
{ | |
// ....working | |
} | |
} | |
public class Human : EmployeeBase | |
{ | |
public override void Work() | |
{ | |
//.... working much more | |
} | |
} | |
public class Robot : EmployeeBase | |
{ | |
public override void Work() | |
{ | |
//.... working much, much more | |
} | |
} | |
public class Manager | |
{ | |
private readonly Robot _robot; | |
private readonly Human _human; | |
public Manager(Robot robot, Human human) | |
{ | |
_robot = robot; | |
_human = human; | |
} | |
public void Manage() | |
{ | |
_robot.Work(); | |
_human.Work(); | |
} | |
} | |
// Good | |
public interface IEmployee | |
{ | |
void Work(); | |
} | |
public class Human : IEmployee | |
{ | |
public void Work() | |
{ | |
// ....working | |
} | |
} | |
public class Robot : IEmployee | |
{ | |
public void Work() | |
{ | |
//.... working much more | |
} | |
} | |
public class Manager | |
{ | |
private readonly IEnumerable<IEmployee> _employees; | |
public Manager(IEnumerable<IEmployee> employees) | |
{ | |
_employees = employees; | |
} | |
public void Manage() | |
{ | |
foreach (var employee in _employees) | |
{ | |
_employee.Work(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment