Object-oriented design implementation of an ElevatorObject Orientated PHP, what's wrong with this implementation of OOPHP and how might it be improved?Cinema schedulingBowling scorecard appPoker Hand classifer part 3: Deck Object and 7 Card HandLeetcode 317: Shortest distance from all buildingsPHP subset of 2 arrays containing objects - compared only by 1 attributeCreating a Student class for a projectChoose your own story text game that executes with loop using choices supplied by playerCourse Management with SOLID principlesExperimenting with a OOP design pattern in JavaScript
C-152 carb heat on before landing in hot weather?
Why is the voltage measurement of this circuit different when the switch is on?
What is the legal status of travelling with (unprescribed) methadone in your carry-on?
Unusual mail headers, evidence of an attempted attack. Have I been pwned?
How risky is real estate?
Why is the Turkish president's surname spelt in Russian as Эрдоган, with г?
What kind of wire should I use to pigtail an outlet?
As a DM, how do you control a dysfunctional group wanting different things out of a game?
Should my manager be aware of private LinkedIn approaches I receive? How to politely have this happen?
Do hotel cleaning personnel have any benefit from leaving empty bottles in the room as opposed to returning them to the store?
Why is there no havdallah when going from Yom Tov into Shabbat?
Catching generic Exception in a toString implementation - bad practice?
Sho, greek letter
Require advice on power conservation for backpacking trip
Are there any vegetarian astronauts?
Cascading Repair Costs following Blown Head Gasket on a 2004 Subaru Outback
Is this one of the engines from the 9/11 aircraft?
Do equal angles necessarily mean a polygon is regular?
Can ADFS connect to other SSO services?
Analog is Obtuse!
Do flight schools typically have dress codes or expectations?
STM Microcontroller burns every time
Apply brace expansion in "reverse order"
First-year PhD giving a talk among well-established researchers in the field
Object-oriented design implementation of an Elevator
Object Orientated PHP, what's wrong with this implementation of OOPHP and how might it be improved?Cinema schedulingBowling scorecard appPoker Hand classifer part 3: Deck Object and 7 Card HandLeetcode 317: Shortest distance from all buildingsPHP subset of 2 arrays containing objects - compared only by 1 attributeCreating a Student class for a projectChoose your own story text game that executes with loop using choices supplied by playerCourse Management with SOLID principlesExperimenting with a OOP design pattern in JavaScript
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
$begingroup$
I am a newbie when it comes to Object Oriented Programming and I have read a lot of online articles and lessons so I want to try it out on my own. I've written a console app in C# and tried implementing Object Oriented Design and SOLID Principles.
The console app checks if a person has an access to a certain floor. Also, The app is in its initial stage so right now the Elevator accomodates a single person.
Although the app works. any feedback,comments, and suggestions will be greatly appreciated especially in terms of SOLID principles or OOP Design.
here is the code below
class Program
static void Main(string[] args)
Person maintenanceEmployee = new MaintenanceEmployee();
Elevator elev = new Elevator(maintenanceEmployee);
elev.GoToFloor(Floors.FourthFloor);
Person guest = new Guest();
Elevator elev2 = new Elevator(guest);
elev2.GoToFloor(Floors.SecondFloor);
Person empfromthirdfloor = new EmployeeFromThirdFloor();
Elevator elev3 = new Elevator(empfromthirdfloor);
elev2.GoToFloor(Floors.ThirdFloor);
Console.ReadLine();
public enum Floors
FirstFloor = 1,
SecondFloor = 2,
ThirdFloor = 3,
FourthFloor = 4,
FifthFloor = 5
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
public class MaintenanceEmployee : Person
public Floors[] _accessibleFloors = Floors.FirstFloor, Floors.SecondFloor, Floors.ThirdFloor, Floors.FourthFloor, Floors.FifthFloor ;
public MaintenanceEmployee()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//in the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class EmployeeFromThirdFloor : Person
public Floors[] _accessibleFloors = Floors.ThirdFloor ;
public EmployeeFromThirdFloor()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class Guest : Person
public Floors[] _accessibleFloors = Floors.SecondFloor ;
public Guest()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
c# beginner object-oriented
New contributor
$endgroup$
add a comment |
$begingroup$
I am a newbie when it comes to Object Oriented Programming and I have read a lot of online articles and lessons so I want to try it out on my own. I've written a console app in C# and tried implementing Object Oriented Design and SOLID Principles.
The console app checks if a person has an access to a certain floor. Also, The app is in its initial stage so right now the Elevator accomodates a single person.
Although the app works. any feedback,comments, and suggestions will be greatly appreciated especially in terms of SOLID principles or OOP Design.
here is the code below
class Program
static void Main(string[] args)
Person maintenanceEmployee = new MaintenanceEmployee();
Elevator elev = new Elevator(maintenanceEmployee);
elev.GoToFloor(Floors.FourthFloor);
Person guest = new Guest();
Elevator elev2 = new Elevator(guest);
elev2.GoToFloor(Floors.SecondFloor);
Person empfromthirdfloor = new EmployeeFromThirdFloor();
Elevator elev3 = new Elevator(empfromthirdfloor);
elev2.GoToFloor(Floors.ThirdFloor);
Console.ReadLine();
public enum Floors
FirstFloor = 1,
SecondFloor = 2,
ThirdFloor = 3,
FourthFloor = 4,
FifthFloor = 5
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
public class MaintenanceEmployee : Person
public Floors[] _accessibleFloors = Floors.FirstFloor, Floors.SecondFloor, Floors.ThirdFloor, Floors.FourthFloor, Floors.FifthFloor ;
public MaintenanceEmployee()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//in the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class EmployeeFromThirdFloor : Person
public Floors[] _accessibleFloors = Floors.ThirdFloor ;
public EmployeeFromThirdFloor()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class Guest : Person
public Floors[] _accessibleFloors = Floors.SecondFloor ;
public Guest()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
c# beginner object-oriented
New contributor
$endgroup$
1
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
1
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04
add a comment |
$begingroup$
I am a newbie when it comes to Object Oriented Programming and I have read a lot of online articles and lessons so I want to try it out on my own. I've written a console app in C# and tried implementing Object Oriented Design and SOLID Principles.
The console app checks if a person has an access to a certain floor. Also, The app is in its initial stage so right now the Elevator accomodates a single person.
Although the app works. any feedback,comments, and suggestions will be greatly appreciated especially in terms of SOLID principles or OOP Design.
here is the code below
class Program
static void Main(string[] args)
Person maintenanceEmployee = new MaintenanceEmployee();
Elevator elev = new Elevator(maintenanceEmployee);
elev.GoToFloor(Floors.FourthFloor);
Person guest = new Guest();
Elevator elev2 = new Elevator(guest);
elev2.GoToFloor(Floors.SecondFloor);
Person empfromthirdfloor = new EmployeeFromThirdFloor();
Elevator elev3 = new Elevator(empfromthirdfloor);
elev2.GoToFloor(Floors.ThirdFloor);
Console.ReadLine();
public enum Floors
FirstFloor = 1,
SecondFloor = 2,
ThirdFloor = 3,
FourthFloor = 4,
FifthFloor = 5
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
public class MaintenanceEmployee : Person
public Floors[] _accessibleFloors = Floors.FirstFloor, Floors.SecondFloor, Floors.ThirdFloor, Floors.FourthFloor, Floors.FifthFloor ;
public MaintenanceEmployee()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//in the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class EmployeeFromThirdFloor : Person
public Floors[] _accessibleFloors = Floors.ThirdFloor ;
public EmployeeFromThirdFloor()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class Guest : Person
public Floors[] _accessibleFloors = Floors.SecondFloor ;
public Guest()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
c# beginner object-oriented
New contributor
$endgroup$
I am a newbie when it comes to Object Oriented Programming and I have read a lot of online articles and lessons so I want to try it out on my own. I've written a console app in C# and tried implementing Object Oriented Design and SOLID Principles.
The console app checks if a person has an access to a certain floor. Also, The app is in its initial stage so right now the Elevator accomodates a single person.
Although the app works. any feedback,comments, and suggestions will be greatly appreciated especially in terms of SOLID principles or OOP Design.
here is the code below
class Program
static void Main(string[] args)
Person maintenanceEmployee = new MaintenanceEmployee();
Elevator elev = new Elevator(maintenanceEmployee);
elev.GoToFloor(Floors.FourthFloor);
Person guest = new Guest();
Elevator elev2 = new Elevator(guest);
elev2.GoToFloor(Floors.SecondFloor);
Person empfromthirdfloor = new EmployeeFromThirdFloor();
Elevator elev3 = new Elevator(empfromthirdfloor);
elev2.GoToFloor(Floors.ThirdFloor);
Console.ReadLine();
public enum Floors
FirstFloor = 1,
SecondFloor = 2,
ThirdFloor = 3,
FourthFloor = 4,
FifthFloor = 5
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
public class MaintenanceEmployee : Person
public Floors[] _accessibleFloors = Floors.FirstFloor, Floors.SecondFloor, Floors.ThirdFloor, Floors.FourthFloor, Floors.FifthFloor ;
public MaintenanceEmployee()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//in the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class EmployeeFromThirdFloor : Person
public Floors[] _accessibleFloors = Floors.ThirdFloor ;
public EmployeeFromThirdFloor()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
public class Guest : Person
public Floors[] _accessibleFloors = Floors.SecondFloor ;
public Guest()
//Not sure if this is the best practice
//Reason why I did it like this is because
//I need to change the arrays of accessibleFloors
//of the abstract class "Person" in order to run successfully
base.accessibleFloors = _accessibleFloors;
c# beginner object-oriented
c# beginner object-oriented
New contributor
New contributor
edited Jun 15 at 11:53
t3chb0t
36k7 gold badges58 silver badges133 bronze badges
36k7 gold badges58 silver badges133 bronze badges
New contributor
asked Jun 15 at 9:11
doctorWeirddoctorWeird
294 bronze badges
294 bronze badges
New contributor
New contributor
1
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
1
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04
add a comment |
1
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
1
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04
1
1
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
1
1
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04
add a comment |
2 Answers
2
active
oldest
votes
$begingroup$
Person + Derived Classes
accessibleFloors
is a breach of Open–closed principle. Anyone is able to modiy this collection.accessibleFloors
could be considered a breach of Single responsibility principle. Consider having aRole
class andPerson
storing hisRoles
set. This way, you can also mitigate redundant code and remove the need of derived classes asEmployeeFromThirdFloor
,Guest
andMaintenanceEmployee
(in this trivial example these classes are not required).accessibleFloors
can benull
. The code is not able to handle this situation.HasAccess
is way to convoluted:accessibleFloors.Contains(_floor);
would do it.
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
We can create a class Role
.
public class Role
public HashSet<Floors> AccessibleFloors get;
public Role (HashSet<Floors> accessibleFloors)
AccessibleFloors = accessibleFloors
?? throw new ArgumentNullException(nameof(accessibleFloors));
public bool HasAccess(Floor floor)
return AccessibleFloors.Contains(floor);
// override equals and gethashcode ..
We can refactor Person
.
public class Person
public HashSet<Role> Roles get;
public Person(HashSet roles)
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
public bool HasAccess(Floors floor)
return Roles.Any(r => r.HasAccess(floor));
Because of Inheritance, the derived classes do not require to create their own instance variable _accessibleFloors
.
base.accessibleFloors = _accessibleFloors;
Elevator
- There is tight-coupling between an
Elevator
and aPerson
. You force the elevator to exist only with a person. What about an empty elevator. GoToFloor
is not usable code. Consider returning aBoolean
and putting theConsole.WriteLine
in the calling code.- The code cannot handle when
Person
isnull
.
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
Elevator
could be refactored as follows.
public class Elevator
public Person Person get; private set;
public bool IsFull => Person != null;
public bool IsEmpty => Person == null;
public bool Enter(Person person)
if (person == null) throw new ArgumentNullException(nameof(person));
if (IsFull) return false;
Person = person;
return true;
public bool Exit(Floors floor)
if (IsEmpty) return false;
if (!Person.HasAccess(floor)) return false;
Person = null;
return true;
Program
class Program
static void Main(string[] args)
var guestRoles = new HashSet<Role>
new Role(new HashSet<Floors> Floors.FirstFloor )
;
var guest = new Person(guestRoles);
var elevator = new Elevator();
if (elevator.Enter(guest))
Console.WriteLine("guest has entered elevator");
else
Console.WriteLine("guest cannot enter elevator: elevator is full");
if (elevator.Exit(Floors.FirstFloor))
Console.WriteLine("guest has exited elevator at FirstFloor");
else
Console.WriteLine("guest cannot exit elevator at FirstFloor: access is denied");
Console.ReadLine();
$endgroup$
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
add a comment |
$begingroup$
If I may add a single consideration to dfhwze's thorough answer:
Having an enum defining floors is OK for a building with 5 floors, but would be overwhelming if we are talking Burj Khalifa with its 163 floors. Besides that it is a rather rigid concept having a predefined number of floors - supposed you want to reuse your object model for other buildings.
Therefore I would create a Floor
class too:
public class Floor
private Floor(string name, int index)
Name = name;
Index = index;
public string Name get;
public int Index get;
public static IEnumerable<Floor> CreateFloors(params string[] names)
return names.Select((n, i) => new Floor(n, i));
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
doctorWeird is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222345%2fobject-oriented-design-implementation-of-an-elevator%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Person + Derived Classes
accessibleFloors
is a breach of Open–closed principle. Anyone is able to modiy this collection.accessibleFloors
could be considered a breach of Single responsibility principle. Consider having aRole
class andPerson
storing hisRoles
set. This way, you can also mitigate redundant code and remove the need of derived classes asEmployeeFromThirdFloor
,Guest
andMaintenanceEmployee
(in this trivial example these classes are not required).accessibleFloors
can benull
. The code is not able to handle this situation.HasAccess
is way to convoluted:accessibleFloors.Contains(_floor);
would do it.
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
We can create a class Role
.
public class Role
public HashSet<Floors> AccessibleFloors get;
public Role (HashSet<Floors> accessibleFloors)
AccessibleFloors = accessibleFloors
?? throw new ArgumentNullException(nameof(accessibleFloors));
public bool HasAccess(Floor floor)
return AccessibleFloors.Contains(floor);
// override equals and gethashcode ..
We can refactor Person
.
public class Person
public HashSet<Role> Roles get;
public Person(HashSet roles)
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
public bool HasAccess(Floors floor)
return Roles.Any(r => r.HasAccess(floor));
Because of Inheritance, the derived classes do not require to create their own instance variable _accessibleFloors
.
base.accessibleFloors = _accessibleFloors;
Elevator
- There is tight-coupling between an
Elevator
and aPerson
. You force the elevator to exist only with a person. What about an empty elevator. GoToFloor
is not usable code. Consider returning aBoolean
and putting theConsole.WriteLine
in the calling code.- The code cannot handle when
Person
isnull
.
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
Elevator
could be refactored as follows.
public class Elevator
public Person Person get; private set;
public bool IsFull => Person != null;
public bool IsEmpty => Person == null;
public bool Enter(Person person)
if (person == null) throw new ArgumentNullException(nameof(person));
if (IsFull) return false;
Person = person;
return true;
public bool Exit(Floors floor)
if (IsEmpty) return false;
if (!Person.HasAccess(floor)) return false;
Person = null;
return true;
Program
class Program
static void Main(string[] args)
var guestRoles = new HashSet<Role>
new Role(new HashSet<Floors> Floors.FirstFloor )
;
var guest = new Person(guestRoles);
var elevator = new Elevator();
if (elevator.Enter(guest))
Console.WriteLine("guest has entered elevator");
else
Console.WriteLine("guest cannot enter elevator: elevator is full");
if (elevator.Exit(Floors.FirstFloor))
Console.WriteLine("guest has exited elevator at FirstFloor");
else
Console.WriteLine("guest cannot exit elevator at FirstFloor: access is denied");
Console.ReadLine();
$endgroup$
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
add a comment |
$begingroup$
Person + Derived Classes
accessibleFloors
is a breach of Open–closed principle. Anyone is able to modiy this collection.accessibleFloors
could be considered a breach of Single responsibility principle. Consider having aRole
class andPerson
storing hisRoles
set. This way, you can also mitigate redundant code and remove the need of derived classes asEmployeeFromThirdFloor
,Guest
andMaintenanceEmployee
(in this trivial example these classes are not required).accessibleFloors
can benull
. The code is not able to handle this situation.HasAccess
is way to convoluted:accessibleFloors.Contains(_floor);
would do it.
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
We can create a class Role
.
public class Role
public HashSet<Floors> AccessibleFloors get;
public Role (HashSet<Floors> accessibleFloors)
AccessibleFloors = accessibleFloors
?? throw new ArgumentNullException(nameof(accessibleFloors));
public bool HasAccess(Floor floor)
return AccessibleFloors.Contains(floor);
// override equals and gethashcode ..
We can refactor Person
.
public class Person
public HashSet<Role> Roles get;
public Person(HashSet roles)
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
public bool HasAccess(Floors floor)
return Roles.Any(r => r.HasAccess(floor));
Because of Inheritance, the derived classes do not require to create their own instance variable _accessibleFloors
.
base.accessibleFloors = _accessibleFloors;
Elevator
- There is tight-coupling between an
Elevator
and aPerson
. You force the elevator to exist only with a person. What about an empty elevator. GoToFloor
is not usable code. Consider returning aBoolean
and putting theConsole.WriteLine
in the calling code.- The code cannot handle when
Person
isnull
.
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
Elevator
could be refactored as follows.
public class Elevator
public Person Person get; private set;
public bool IsFull => Person != null;
public bool IsEmpty => Person == null;
public bool Enter(Person person)
if (person == null) throw new ArgumentNullException(nameof(person));
if (IsFull) return false;
Person = person;
return true;
public bool Exit(Floors floor)
if (IsEmpty) return false;
if (!Person.HasAccess(floor)) return false;
Person = null;
return true;
Program
class Program
static void Main(string[] args)
var guestRoles = new HashSet<Role>
new Role(new HashSet<Floors> Floors.FirstFloor )
;
var guest = new Person(guestRoles);
var elevator = new Elevator();
if (elevator.Enter(guest))
Console.WriteLine("guest has entered elevator");
else
Console.WriteLine("guest cannot enter elevator: elevator is full");
if (elevator.Exit(Floors.FirstFloor))
Console.WriteLine("guest has exited elevator at FirstFloor");
else
Console.WriteLine("guest cannot exit elevator at FirstFloor: access is denied");
Console.ReadLine();
$endgroup$
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
add a comment |
$begingroup$
Person + Derived Classes
accessibleFloors
is a breach of Open–closed principle. Anyone is able to modiy this collection.accessibleFloors
could be considered a breach of Single responsibility principle. Consider having aRole
class andPerson
storing hisRoles
set. This way, you can also mitigate redundant code and remove the need of derived classes asEmployeeFromThirdFloor
,Guest
andMaintenanceEmployee
(in this trivial example these classes are not required).accessibleFloors
can benull
. The code is not able to handle this situation.HasAccess
is way to convoluted:accessibleFloors.Contains(_floor);
would do it.
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
We can create a class Role
.
public class Role
public HashSet<Floors> AccessibleFloors get;
public Role (HashSet<Floors> accessibleFloors)
AccessibleFloors = accessibleFloors
?? throw new ArgumentNullException(nameof(accessibleFloors));
public bool HasAccess(Floor floor)
return AccessibleFloors.Contains(floor);
// override equals and gethashcode ..
We can refactor Person
.
public class Person
public HashSet<Role> Roles get;
public Person(HashSet roles)
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
public bool HasAccess(Floors floor)
return Roles.Any(r => r.HasAccess(floor));
Because of Inheritance, the derived classes do not require to create their own instance variable _accessibleFloors
.
base.accessibleFloors = _accessibleFloors;
Elevator
- There is tight-coupling between an
Elevator
and aPerson
. You force the elevator to exist only with a person. What about an empty elevator. GoToFloor
is not usable code. Consider returning aBoolean
and putting theConsole.WriteLine
in the calling code.- The code cannot handle when
Person
isnull
.
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
Elevator
could be refactored as follows.
public class Elevator
public Person Person get; private set;
public bool IsFull => Person != null;
public bool IsEmpty => Person == null;
public bool Enter(Person person)
if (person == null) throw new ArgumentNullException(nameof(person));
if (IsFull) return false;
Person = person;
return true;
public bool Exit(Floors floor)
if (IsEmpty) return false;
if (!Person.HasAccess(floor)) return false;
Person = null;
return true;
Program
class Program
static void Main(string[] args)
var guestRoles = new HashSet<Role>
new Role(new HashSet<Floors> Floors.FirstFloor )
;
var guest = new Person(guestRoles);
var elevator = new Elevator();
if (elevator.Enter(guest))
Console.WriteLine("guest has entered elevator");
else
Console.WriteLine("guest cannot enter elevator: elevator is full");
if (elevator.Exit(Floors.FirstFloor))
Console.WriteLine("guest has exited elevator at FirstFloor");
else
Console.WriteLine("guest cannot exit elevator at FirstFloor: access is denied");
Console.ReadLine();
$endgroup$
Person + Derived Classes
accessibleFloors
is a breach of Open–closed principle. Anyone is able to modiy this collection.accessibleFloors
could be considered a breach of Single responsibility principle. Consider having aRole
class andPerson
storing hisRoles
set. This way, you can also mitigate redundant code and remove the need of derived classes asEmployeeFromThirdFloor
,Guest
andMaintenanceEmployee
(in this trivial example these classes are not required).accessibleFloors
can benull
. The code is not able to handle this situation.HasAccess
is way to convoluted:accessibleFloors.Contains(_floor);
would do it.
public abstract class Person
public Floors[] accessibleFloors;
public bool HasAccess(Floors _floor)
foreach (Floors i in accessibleFloors)
if (_floor == i)
return true;
return false;
We can create a class Role
.
public class Role
public HashSet<Floors> AccessibleFloors get;
public Role (HashSet<Floors> accessibleFloors)
AccessibleFloors = accessibleFloors
?? throw new ArgumentNullException(nameof(accessibleFloors));
public bool HasAccess(Floor floor)
return AccessibleFloors.Contains(floor);
// override equals and gethashcode ..
We can refactor Person
.
public class Person
public HashSet<Role> Roles get;
public Person(HashSet roles)
Roles = roles ?? throw new ArgumentNullException(nameof(roles));
public bool HasAccess(Floors floor)
return Roles.Any(r => r.HasAccess(floor));
Because of Inheritance, the derived classes do not require to create their own instance variable _accessibleFloors
.
base.accessibleFloors = _accessibleFloors;
Elevator
- There is tight-coupling between an
Elevator
and aPerson
. You force the elevator to exist only with a person. What about an empty elevator. GoToFloor
is not usable code. Consider returning aBoolean
and putting theConsole.WriteLine
in the calling code.- The code cannot handle when
Person
isnull
.
public class Elevator
Person person;
public Elevator(Person _person)
this.person = _person;
public void GoToFloor(Floors _floor)
if (person.HasAccess(_floor))
Console.WriteLine("Elevating to " + _floor.ToString());
else
Console.WriteLine("No Access to " + _floor.ToString());
Elevator
could be refactored as follows.
public class Elevator
public Person Person get; private set;
public bool IsFull => Person != null;
public bool IsEmpty => Person == null;
public bool Enter(Person person)
if (person == null) throw new ArgumentNullException(nameof(person));
if (IsFull) return false;
Person = person;
return true;
public bool Exit(Floors floor)
if (IsEmpty) return false;
if (!Person.HasAccess(floor)) return false;
Person = null;
return true;
Program
class Program
static void Main(string[] args)
var guestRoles = new HashSet<Role>
new Role(new HashSet<Floors> Floors.FirstFloor )
;
var guest = new Person(guestRoles);
var elevator = new Elevator();
if (elevator.Enter(guest))
Console.WriteLine("guest has entered elevator");
else
Console.WriteLine("guest cannot enter elevator: elevator is full");
if (elevator.Exit(Floors.FirstFloor))
Console.WriteLine("guest has exited elevator at FirstFloor");
else
Console.WriteLine("guest cannot exit elevator at FirstFloor: access is denied");
Console.ReadLine();
edited Jun 15 at 11:02
answered Jun 15 at 10:43
dfhwzedfhwze
3,1161 gold badge6 silver badges31 bronze badges
3,1161 gold badge6 silver badges31 bronze badges
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
add a comment |
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
1
1
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
$begingroup$
wow, I appreciate the remodelling and refactoring of the code. Thank you.
$endgroup$
– doctorWeird
Jun 15 at 11:33
add a comment |
$begingroup$
If I may add a single consideration to dfhwze's thorough answer:
Having an enum defining floors is OK for a building with 5 floors, but would be overwhelming if we are talking Burj Khalifa with its 163 floors. Besides that it is a rather rigid concept having a predefined number of floors - supposed you want to reuse your object model for other buildings.
Therefore I would create a Floor
class too:
public class Floor
private Floor(string name, int index)
Name = name;
Index = index;
public string Name get;
public int Index get;
public static IEnumerable<Floor> CreateFloors(params string[] names)
return names.Select((n, i) => new Floor(n, i));
$endgroup$
add a comment |
$begingroup$
If I may add a single consideration to dfhwze's thorough answer:
Having an enum defining floors is OK for a building with 5 floors, but would be overwhelming if we are talking Burj Khalifa with its 163 floors. Besides that it is a rather rigid concept having a predefined number of floors - supposed you want to reuse your object model for other buildings.
Therefore I would create a Floor
class too:
public class Floor
private Floor(string name, int index)
Name = name;
Index = index;
public string Name get;
public int Index get;
public static IEnumerable<Floor> CreateFloors(params string[] names)
return names.Select((n, i) => new Floor(n, i));
$endgroup$
add a comment |
$begingroup$
If I may add a single consideration to dfhwze's thorough answer:
Having an enum defining floors is OK for a building with 5 floors, but would be overwhelming if we are talking Burj Khalifa with its 163 floors. Besides that it is a rather rigid concept having a predefined number of floors - supposed you want to reuse your object model for other buildings.
Therefore I would create a Floor
class too:
public class Floor
private Floor(string name, int index)
Name = name;
Index = index;
public string Name get;
public int Index get;
public static IEnumerable<Floor> CreateFloors(params string[] names)
return names.Select((n, i) => new Floor(n, i));
$endgroup$
If I may add a single consideration to dfhwze's thorough answer:
Having an enum defining floors is OK for a building with 5 floors, but would be overwhelming if we are talking Burj Khalifa with its 163 floors. Besides that it is a rather rigid concept having a predefined number of floors - supposed you want to reuse your object model for other buildings.
Therefore I would create a Floor
class too:
public class Floor
private Floor(string name, int index)
Name = name;
Index = index;
public string Name get;
public int Index get;
public static IEnumerable<Floor> CreateFloors(params string[] names)
return names.Select((n, i) => new Floor(n, i));
answered Jun 15 at 12:37
Henrik HansenHenrik Hansen
9,5581 gold badge13 silver badges34 bronze badges
9,5581 gold badge13 silver badges34 bronze badges
add a comment |
add a comment |
doctorWeird is a new contributor. Be nice, and check out our Code of Conduct.
doctorWeird is a new contributor. Be nice, and check out our Code of Conduct.
doctorWeird is a new contributor. Be nice, and check out our Code of Conduct.
doctorWeird is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f222345%2fobject-oriented-design-implementation-of-an-elevator%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
Is it safe to assume an elevator can at most contain 1 person?
$endgroup$
– dfhwze
Jun 15 at 9:43
1
$begingroup$
Please add a description about what you application does. Elevator Sample is too general.
$endgroup$
– t3chb0t
Jun 15 at 9:56
$begingroup$
@dfwze well for now this is just its initial design, at this stage I just like to know if the coding is on track in terms of OOP or SOLID.
$endgroup$
– doctorWeird
Jun 15 at 10:04