If the inheritance was used to simply share attributes or behavior without further adding anything special in subclasses? then you're misusing inheritance, The indication of misuse, because there is no point for the subclasses to exists since the superclass already is enough.
Liskov Substitution Principle.
The principle states that a subclass can replace a superclass, if and only if, the subclass does not change the functionality of the superclass.
how do you make sure that the system you've created is correct?
do a Model checking: is a systematic check of your system's state modelin all its possible states.
model checking is a technique that does state exploration
start in this current state,explore all the possible ways you can go into the future and reason about what all those possible future states can look like.
model checking relies on is the ability for you to take your piece of code and extract from your piece of code just those parts of the problem that you need to model.
if you can specify what your system does, you can write test for it.In some sense, test are themselves specifications.
Because if you pass it, it's doing the right thing, if you don't pass it,it's doing the wrong thing.If you can model check your system, that's good,because it means that you have some specifications that don't need test cases.
Model checking is similar and that it checks the behavior in the state model for the system and notifies of any violations to the rules.A rule that your software is required to satisfy is it must not produce a deadlock.
A deadlock is a situation where your system cannot continue because two tasks are waiting for the same resource.
Your model checker would simulate the different states that could occur in your system and if a deadlock is possible, it would provide details of the violation.
Model checkers generate a State Model from your code
A state model is an abstract state machine that can be in one of various states.The model checker then checks that the state model conforms to certain behavioral properties
There are three different phases to performing model checking, the modeling phase, the running phase, and the analysis phase.
there are many ways to test the system's behaviour, like unit testing,beta testing, and simulations.
Aggregation is used to represent a "has a" or "weak containment" relationship between two objects.
Use that "has a" relationship to build a stack of objects where each level of the stack contains an object that knows about its own behavior and augments the one underneath it in the stack. This is what an aggregation stack looks like.
Information hiding allows models of our system to give others the minimum amount of information needed to use them correctly and hide everything else.
Information hiding is often associated with encapsulation
We use encapsulation to bundle attributes and behaviors into their appropriate class, and expose an interface to provide access.
You can hide information through the use of access modifiers.
The term module refer to any sort of program unit like: Classes (Java)
Encapsulation is a fundamental design principle in object oriented modeling and programming
Encapsulation involves three ideas. As the name suggests, it's about making a sort of capsule.The capsule contains something inside, some of which you can access from the outside, and some of which you cannot.
First, you bundle attribute values or data,and behaviors or functions, that manipulate those values together into a self-contained object.
Second, you can expose certain data and functions of that object, which can be accessed from other objects.
Third, you can restrict access to certain data and functions to only within that object.
In short, encapsulation forms a self-contained object by bundling the data and functions it requires to work, exposes an interface whereby other objects can access and use it, and restricts access to certain inside details.
An object's data should only contain what is relevant for that object.
In programming, this sort of thinking is commonly referred to as, Black Box Thinking. Think of a class like a black box that you cannot see inside for details about, how attributes are represented, or how methods compute the result, but you provide inputs and obtain outputs by calling methods. It doesn't matter what happens in the box to achieve the expected behaviors. This distinction between what the outside world sees of a class, and how it works internally is important.
Encapsulation achieves what is called, the Abstraction Barrier. Since the internal workings are not relevant to the outside world, this achieves an abstraction that effectively reduces complexity for the users of a class. This increases re-usability, because another class only needs to know the right method to call to get the desired behavior, what arguments to supply as inputs, and what appear as outputs or effects.
Encapsulation helps with software changes. The accessible interface of a class can remain the same, while the implementation of the attributes and methods can change. Outsiders using the class, do not need to care how the implementation actually works behind the interface.
Encapsulation can secure sensitive information
Encapsulation is a key design principle in achieving a well written program. It keeps your software modular and easier to work with. It also keeps your classes easy to manage, whose behaviors are accessed like black boxes.
Coupling and Cohesion
The metrics used to evaluate design complexity
Focus on complixity within the module
how many responsibilities assigned to the module: 1- High Cohesion: if the module perform one task 2- Low cohesion: if the module perform two or more tasks.
Coupling focuses on complexity between a module and other modules
The connecting between the module can be evaluated in two complixity levels: 1- Tightly coupled: if the module tightly coupled to another modules 2- Loosley coupled: if the module was easy to connect to another modules
Coupling considration: 1- Degree: The number of connection between the module and other modules, fewer degress means loosley coupling 2- Ease: means, how easy the connection between the module and others. 3- Flexability: means how easy is the changabilities of other modules to this module
Separation of concern
separation of concerns, is a key idea that applies throughout object oriented modelling and programming.
The concerns that matter are addressed separately when applying the design
principles of obstruction, encapsulation, decomposition, and generalization.
Conceptual integrity is about creating consistent software. It's making decisions about how your system will be designed and implemented
There are multiple ways to achieve conceptual integrity. - One important way is communication. Adopting certain agile development practices. - The consistency of the code. For example, team members can all follow a particular naming convention. - Code reviews. - Additionally, using certain design principles and programming constructs can also help in maintaining conceptual integrity. Consider interfaces.
A well defined design or architecture underlying your software. While software design is typically associated with guiding the internal design of software running as a single process, software architecture describes how software, running as multiple processes, work together, and how they relate to each other. Much like using certain design principles, having a strong software design or architecture to guide how your software is organized creates consistency.
Unifying concepts is also another approach to maintaining conceptual integrity. It is taking seemingly different things and finding common ground so that each concepts can be seen and treated in similar ways. Unifying concepts to avoid special cases can provide consistency in software.
Having a small core group that accepts commits to the code
Conceptual integrity is the most important consideration in system design.it is better to have a system omit certain anomalous features and improvements, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.
Practicing conceptual integrity in software can help guide team when they are making modificarion.
Keeping things consistent and logical would make it much easier to maintain and work with