SOLID : SRP + ISP - solid-principles

I am trying to understand SOLID principles. I think I understand well the Liskov Substitution Principle, but I have some problems for other ones.
One example. I have two interfaces : Engine and car stereo.
The problem is : For a car, we have 6 glasses.
So, my car implements interfaces Engine and Car Stereo.
But for the 6 glasses, should I implement them, or should I put them on an array of glasses knowing there are 4 laterals glasses which are able to be up or down and 2 windshields (glasses inherited by both).
The problem with the first one is, I can't implement 4 times the same glasses.
So the second one seems to me good but I am afraid that break SRP, I am not sure to understand what "Responsibilities" exactly are.

The correct design practise is to
code to interface rather than class.
In light of this principle I'd recommend to use a interfaces like IWindow, ISurface, IWindShield with a hierarchy like below
interface ISurface
{
//surface specific properties which ideally should be DI-ed
public SurfaceType SurfaceType {get; set;}
public decimal Opacity {get;set;}
public decimal Thickness {get; set;}
}
and
interface IWindow:ISurface
{
//Window behavior specific properties and methods
public void lowerWindow();
public WindowHeight WindowLevel(){get;set;}
public void shutWindow();
// ...and more such window specific behavior
}
and
interface IWindShield:ISurface
{
//WindShield behavior specific properties and methods
public bool IsFogged(){get;set;}
public bool IsClean(){get;set;}
// ...and more such window specific behavior
}
Finally when assembling a car with all its functionality (presumably using a Builder pattern), you can have an array in the Car class of type ISurface type like below
class Car
{
string carName;
Engine carEngine;
Stereo carStereo;
List<ISurface> carGlasses;
.....
// other Car parts
// this is a typical builder pattern example
}
this is build using a CarBuilder type class say MyCarBuilder where
interface CarBuilder
{
public Car MyCar {get; set;}
void AddEngine();
void AddStereo();
void AddGlasses();// this is what works on adding ISurface List items
// and other car building methods
}
and the real builder class
class MyCarBuilder:CarBuilder
{
//... implements all methods of building your custom car
}

It really depends on intended use, but lets take car functional domain (invented on the spot) for example.
Your implementation class will implement IMotor (Tesla D has two motors), IEntertainmentCentre (lets hope there is one), IGlassSurface (could be quite a number in SUV). In each interface you will specify which motor/glass-surface you are addressing, for example: IGlassSurface.Operate(glassSurfaceId, direction, distance).

Related

Is "one method per class" overdoing the Single Responsibility Principle?

I'm building a simple todo list application on android because I want to get myself familiar with the clean architecture. I layered the application with domain, data and presentation layer, and here is the example i'm following: https://github.com/android10/Android-CleanArchitecture
When I tried to figure out what is the domain for this application, I asked myself "what is this application about?". To which I reply, "It is about letting user create a group and create tasks within that group", very simple,
So I created the following:
Adding groups to Room database
public class AddGroupItemUseCase extends AbstractUseCaseCompletable<AddGroupItemUseCase.Params> {
private final GroupItemRepository mGroupItemRepository;
public AddGroupItemUseCase(GroupItemRepository repository,
PostExecutionThread postExecutionThread,
ThreadExecution threadExecution) {
super(threadExecution, postExecutionThread);
mGroupItemRepository = repository;
}
#Override
public Completable buildUseCaseCompletable(Params params) {
return mGroupItemRepository.addItemToGroup(params.mItem);
}
public static final class Params {
private final Item mItem;
private Params(Item item) {
mItem = item;
}
public static Params itemToBeAdded(Item item) {
return new Params(item);
}
}
}
Adding tasks to a group in Room database:
public class AddGroupUseCase extends AbstractUseCaseCompletable<AddGroupUseCase.Params> {
private final GroupRepository mGroupRepository;
public AddGroupUseCase(ThreadExecution threadExecution,
PostExecutionThread postExecutionThread,
GroupRepository repository) {
super(threadExecution, postExecutionThread);
mGroupRepository = repository;
}
#Override
public Completable buildUseCaseCompletable(Params params) {
return mGroupRepository.addGroup(params.mGroup);
}
public static final class Params {
private final Group mGroup;
private Params(Group group) {
mGroup = group;
}
public static AddGroupUseCase.Params groupToAdd(Group group) {
return new AddGroupUseCase.Params(group);
}
}
}
So, an obvious question arises, do I have to create these one class one method classes for every crud operation? For example, what if I want to get know how many tasks are in a group? do I have to create a class with that method in order to comply with the clean architecture? feels like a lot of classes need to be created, but I guess it make sense because of SRP but then you would have a lot of "functional classes" you need to keep up with,
any thoughts? thank you!
Yes! You should not have "one class one method".
Responsibility in SRP doesn't mean doing just one single task, it means holding all responsibility in single domain. So doing everything within a single concern, which is not overlapping with another class. You can have one class to do everything with "groups", and one class to do everything with "tasks". This is how things are normally organized.
From Wikipedia:
The single-responsibility principle says that these two aspects of the problem are really two separate responsibilities, and should therefore be in separate classes or modules. ... The reason it is important to keep a class focused on a single concern is that it makes the class more robust.

Type-safe IDs in service layer for error prevention

I'm currently writing on the business logic of an Java-application. I've splitted it into domain layer and service layer. The service layer provides interfaces which allow access on the data via data transfer objects.
The idea i've got is to make "typesafe" IDs. That could be simple described as that the method getId() doesn't return a long but instead an object of an special class which consists of the ID value and also a Class-field to determine the type which object is referred. The motivation befind this is, that I used the ID of the wrong type which lead to a difficult-to-detect error.
The ID-Class would look something like this:
public class ObjectId<T>
{
private Class<T> type;
prviate long id;
...
}
The class is then used in a DTO:
public class SomeDTO
{
public ObjectId<SomeDTO> getId(){...}
...
}
and also in the service:
public interface TheService
{
public SomeDTO getSome(ObjectId<SomeDTO> id);
...
}
I might be completly wrong, but beside some drawbacks like a more complex model it also offers the possibility to prevent such errors at the outsets.
Is it a good or a crazy idea?

What are some easy to understand *bad* examples of using inheritance?

I'm looking for bad examples of using inheritance. I'm not very creative so this was the best I could think of:
class Car : public Engine {}
A car has an engine, but it is not an engine.
This would probably work to explain the concept, but I believe there are more illustrative examples?
The "classic" example ;-):
public class Stack extends Vector {
...
}
A Stack is NOT a Vector.
If Stack extends Vector, you are able to insert/delete at every given index, whereas you should only be allowed to add/delete elements by pushing/popping.
Use pretty much any example that uses inheritance without regard to the behavior of the base class.
A classic example is the relationship between Square and Rectangle. Sure, in mathematics, a square is a type of a rectangle. However, in software design, a square doesn't behave like a rectangle:
public class Rectangle
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }
}
public class Square : Rectangle
{
public override int Width
{
get { return base.Width; }
set
{
base.Width = value;
base.Height = value;
}
}
public override int Height
{
get { return base.Height; }
set
{
base.Height= value;
base.Width = value;
}
}
}
If another class, Client, needs a Rectangle but gets a Square, Client will break because it expects its Rectangle to have a Width and Height that don't affect each other.
Inheritance is very useful, but also breaks encapsulation. This means that your subclasses depend on implementation details of the superclass; if the superclass changes, your subclass may break. Here's an example in Java, from Effective Java by Josh Bloch:
public class InstrumentedHashSet<E> extends HashSet<E> {
// number of attempted element insertions
private int addCount = 0;
public int getAddCount() {
return addCount;
}
#Override public boolean addAll<Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
}
The problem is that HashSet's addAll() method uses its add() method internally, but doesn't document this. So if you try
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
you end up with a count of 6 instead of 3. In this particular case that isn't very harmful, but if you were adding a large collection or doing some other operation, it could be.
So, concrete classes are usually not a good idea to inherit from, unless they were designed to have subclasses.
This have been debated for years, and you'll find a lot of materials/talks referencing the problem on google.
public class Square extends Rectangle {
...
}
Perhaps not very surprising though, a square should not inherit from a rectangle.

Language Agnostic Basic Programming Question

This is very basic question from programming point of view but as I am in learning phase, I thought I would better ask this question rather than having a misunderstanding or narrow knowledge about the topic.
So do excuse me if somehow I mess it up.
Question:
Let's say I have class A,B,C and D now class A has some piece of code which I need to have in class B,C and D so I am extending class A in class B, class C, and class D
Now how can I access the function of class A in other classes, do I need to create an object of class A and than access the function of class A or as am extending A in other classes than I can internally call the function using this parameter.
If possible I would really appreciate if someone can explain this concept with code sample explaining how the logic flows.
Note
Example in Java, PHP and .Net would be appreciated.
Let's forget about C and D because they are the same as B. If class B extends class A, then objects of type B are also objects of type A. Whenever you create an object of type B you are also creating an object of type A. It should have access to all of the methods and data in A (except those marked as private, if your language supports access modifiers) and they can be referred to directly. If B overrides some functionality of A, then usually the language provides a facility to call the base class implementation (base.Foo() or some such).
Inheritance Example: C#
public class A
{
public void Foo() { }
public virtual void Baz() { }
}
public class B : A // B extends A
{
public void Bar()
{
this.Foo(); // Foo comes from A
}
public override void Baz() // a new Baz
{
base.Baz(); // A's Baz
this.Bar(); // more stuff
}
}
If, on the other hand, you have used composition instead of inheritance and B contains an instance of A as a class variable, then you would need to create an object of A and reference it's (public) functionality through that instance.
Composition Example: C#
public class B // use A from above
{
private A MyA { get; set; }
public B()
{
this.MyA = new A();
}
public void Bar()
{
this.MyA.Foo(); // call MyA's Foo()
}
}
depending on the access level (would be protected or public in .NET), you can use something like:
base.method(argumentlist);
the base keyword in my example is specific to C#
there is no need for an instance of class A, because you already have a class A inherited instance
Basically you need a reference to the parent class.
In PHP:
parent::example();
From: http://www.php.net/manual/en/keyword.parent.php
<?php
class A {
function example() {
echo "I am A::example() and provide basic functionality.<br />\n";
}
}
class B extends A {
function example() {
echo "I am B::example() and provide additional functionality.<br />\n";
parent::example();
}
}
$b = new B;
// This will call B::example(), which will in turn call A::example().
$b->example();
?>
I find that the best way to tame the complexity of inheritance is to ensure that I only make B inherit from A when it really is a specialization of the superclass. At that point, I can call A's methods from inside B just as if they were B's own methods, and if B has overridden them then I can only suppose that this must be for a good reason.
Of course, quite often it is useful for B's implementation of a method to invoke A's implementation on the same object, generally because the subclass is wrapping extra behavior around the superclass's basic definition. The way in which you do this varies between languages; for example, in Java you do this:
super.methodName(arg1, ...);
Here's a quick Java example:
public class Aclass
{
public static void list_examples()
{
return("A + B = C");
}
}
public class Bclass extends Aclass
{
public static void main(String [] args)
{
System.out.println("Example of inheritance "+list_examples);
}
}
Note that the method for accessing the parent class shouldn't change. Because you are extending you shouldn't have to say parent:: or anything unless you are overriding the parent method / function.
It seems to me that extending your class might not be your best option. Class "B", "C", and "D" should only extend class "A" if they are truly an extension of that class, not just to access some method. For instance "Huffy" should not extend "BrandNames" just because "Huffy" is a brand name and you want access to one of the methods of "BrandNames". "Huffy" should instead extend "Bicycle" and implement an interface so the methods of "BrandNames" can be used. An additional benefit here is that (in Java) multiple interfaces can be used but a class can only be extended once. If in your example class "B"' needed to access a method from class "A" that could work, but if class "C" needed to access a method from class "A" and class "'B"' then you would have to use an interface in class "'C".

Can anybody explain the concept of pluggable adapter to me with good example?

Can anybody explain the concept of pluggable adapter to me with good example?
From what I understood from a quick reading of Google results, a pluggable adapter is an adapter that isn't hard-coded against a specific adaptee. On the surface (the adapter's own interface), it's all the same but it can adapt to different adaptees with different interfaces. I found this thread pretty explanatory:
Basically, it allows you to put in an
adapter when the adaptee (receiver)
protocol is not known at compile time
by using reflection. When you create
the adapter instance, you pass it the
name of the adaptee's method to call,
and also any metadata that's necessary
to translate input types. When the
adapter receives a method call of the
target interface, it uses reflection
to call the corresponding method
specified on the adaptee.
And this:
The main responsibility of the Viewer
is to populate a widget from a domain
model without making any assumptions
about domain itself. JFace viewer uses
the Delegating Objects mechanism in
Pluggable Adapter Pattern to implement
the above requirement.
Think of it as a facehugger from Alien; when it hugs a face, all you see is the slimy back of the facehugger. You can poke it with a stick and try to pry off its arms (the adapter interface). But it basically can hug the face of any human (the adaptee), regardless of the face features. Maybe I'm pushing it a bit, but, hey, I love Alien.
You can read this article about adapter/pluggable pattern:
Table of content in this article:
* 1 Design Patterns
* 2 Intent of Adapter
* 3 Motivation
* 4 Structure
* 5 Applicability
* 6 Consequences
* 7 Implementation
o 7.1 Known Uses and Sample Code
o 7.2 Related Patterns
* 8 Conclusions
* 9 Appendix
o 9.1 References
o 9.2 Glossary
Quote:
Smalltalk introduced the concept of a
"pluggable adapter" to describe
classes with built-in interface
adaptation. This interesting concept
allows for classes to be introduced
into existing systems that might
expect different interfaces to the
class. This technique can help promote
class reuse across modules and even
projects.
Here is a small example:
We have two classes - Foo & Boo that outputs some string to console. Adapter class can adapt methods from both classes to provide interface (SaySomething) required by client. Note that there is no dependency on interface name - we can easily adapt both SayHey and Bark methods.
class Foo
{
public static void SayHey() { Console.WriteLine("Hey!"); }
}
class Boo
{
public static void Bark() { Console.WriteLine("Woof!"); }
}
class Adapter
{
public Action SaySomething { get; private set;} // "pluggable" adapter
public Adapter(Action saySomethingAction)
{
SaySomething = saySomethingAction;
}
}
class Program
{
static void Main(string[] args)
{
(new Adapter(Foo.SayHey)).SaySomething();
(new Adapter(Boo.Bark)).SaySomething();
}
}
A distinguish Feature of the Pluggable Adapter is that the method called by the client and the method existing in the interface can be different.
interface Ilegacy
{
float calculate(int a, int b);
}
class Legacy : Ilegacy
{
public float calculate(int a, int b)
{
return a * b;
}
}
class Adapter
{
public Func<int, int, float> legacyCalculator;
public Adapter()
{
this.legacyCalculator = new Legacy().calculate;
}
}
class Client
{
static void Main()
{
float result = new Adapter().legacyCalculator(5, 6);
}
}
This can normally acheived with the use of delegate,Func or Action in C#