Showing posts with label OOAD. Show all posts
Showing posts with label OOAD. Show all posts

Saturday, 16 September 2023

SOLID Principles

S: Single responsibility.

 A class or a method, there is only one reason to change it. 

In simple terms, the Single Responsibility Principle states that a class or method should be designed to serve a single, well-defined functionality. This makes it easier to test and maintain, as each class or method is focused on a specific responsibility and can be tested in isolation.

In coding practices, it's essential to separate responsibilities during system design.

For example, when you need to instantiate an HTTP client, consider creating a Factory Class solely dedicated to producing HttpClient instances. In this design approach, another class, named ClientConfiguration, would be responsible only for gathering and storing all client configuration parameters. This configuration would then be passed as an input argument to the Factory.

O: Open-Close principle. 

Objects or entities open for extension but close for modification. 

Once a class and its methods have been implemented and tested, especially already in production, then modifying its code may lead to side effects. So it is considered to be closed to make code changes to it.

So making a new behaviours based on an existing Java class, maybe by extending and overriding the existing method, or by decorating the existing one with a wrapper. They are using the same principle extension and then overriding the parent behaviour, and thus without modifying the existing behaviour, it gives a new behaviour based on the legacy class. 


L: Liskov Substitution Principle(Barara Liskov)

From the O: principle, we may already know, we probably need this L: principle.
All subtypes of a A class, may substitute A, and won't disrupt the current system behaviours.   

I: Interface Segregation principle. 

The reason why we need to segregate interfaces according to different usage perspectives is to avoid forcing clients to depend on interfaces that they do not use. By designing interfaces that are specific to the needs of the clients, we can ensure that clients only depend on the interfaces that they actually need, which promotes flexibility, modularity, and maintainability in the codebase.

D: Dependency Inversion Principle.

By depending on abstractions rather than concrete implementations, strong connections between modules or layers can be decoupled. This allows for the replacement of the concrete implementation of dependent abstractions without disrupting upper layers(modifying its code), and also upper layer classes become reusable for removing dependency on a concrete implementation. The purpose to decouple classes is to achieve independence and set up a clear boundary between classes.  In this way, it may be reused to handle the same problem in different contexts, so it is a way to DRY code in coding practice.



Tuesday, 14 April 2020

Polymorphism

Polymorphism is the ability of an object to take on many forms. In OOP polymorphism is implemented by the Inheritance.

In Java, any class is polymorphic. Any class Is-A Object, meanwhile IS-A form of itself. At least, a class has two forms.

An abstract class, a superclass, or an interface, may have different forms due to their derivatives.  A derivative may have many different forms.

Virtual method refers to a method is a method that is overridden by a child class. Its implementation is determined by its run time implementation instance.





Saturday, 18 June 2016

OOAD: Overloading



The purpose of overloading is to re-use the method signature. 

Overload Methods

Overloading is distinguished and validated only by input augment lists. 

  • The change in the number of parameters that are accepted.
  • The change in the type of method parameters that are accepted.
  • The change in the positions of the parameters that are accepted
public void method(float m1, int m2){}
public void method(int m2, float m1){}

The sequence of parameters can create different argument lists, so it is valid overloading. 

Overloading methods cannot be validated by differing return types. 
double calcAverage(int m1, int m2){}
int calcAverage(int m1, int m2){}
the above is invalid overloading and leading to a compiling error. 

Overloading methods cannot be validated by differing access modifiers
Overloading method cannot be validated by differing non-access modifiers


When the class don't share an inheritance relationship, there isn't any confusion with the version of the method that will be called. 

Class Base{}
Class A extends Base{}
Class B extends Base{}

A and B they both in a different branch of the inheritance tree, they are not a confusion;
However, A and Base are on the same inheritance branch; they may create confusion. 
A is a Base; while Base is also Base;  These two types may confusing the overloading. 

Class Reception{
public void accept(Base var){} //1
public void accept(A var){}//2
}

If invoking accept(new A()); Which overloading method will be called?
here the A instance is created, so //2 should be invoked. 

The overloaded methods are bound at the compiling time but not runtime. 

In another way: 
Base a = new A();
accept(a)

On the compiling time, a is considered as a Base class type because of the reference variable type, the //1 is therefore invoked. 


Overloaded Constructors

  • Overloaded Constructor must be defined using a different argument list. 
  • Overloaded Constructors cannot be validated by differing only the access modifiers. 
Using this key to refer to other overloaded constructors in a constructor; it is a common mistake to use a Class name to refer to other overloaded constructors in a constructor. 

Using non-access modifiers with constructors is illegal. The code won't compile. 



In the following case, imagine what will the output?
/**
 *
 * @author YNZ
 */
class TestClass {

    void probe(int... x) {
        System.out.println("In ...");
    } //1

    void probe(Integer x) {
        System.out.println("In Integer");
    } //2

    void probe(long x) {
        System.out.println("In long");
    } //3

    void probe(Long x) {
        System.out.println("In LONG");
    } //4

    void probe(Object x) {
        System.out.println("In Object");
    } //5

    void probe(int x) {
        System.out.println("In int");
    } //6

    public static void main(String[] args) {
        Integer a = 4;
        new TestClass().probe(a); //5
        Long b = 4L;
        new TestClass().probe(b); //6
        byte c = 100;
        new TestClass().probe(c);
        char d = 'a';
        new TestClass().probe(d);
        int e = 10;
        new TestClass().probe(e);
        String str ="aha";
        new TestClass().probe(str);
        int[] array = new int[3];
        new TestClass().probe(array);
        

    }
}



Tuesday, 24 May 2016

Java Access Modifier


                             
public: anywhere.
protected: accessible by classes within in the same package, and sub-class outside the package.
default: only access within the class and classes in the same package.
private:  only access within the class, not accessible even by the sub-classes.

The following example will show a compiling error, for A constructor using default modifier cannot be accessible outside the package. So it causes sub-class to init. error as calling super().

//File A.java
package a;

public class A {

    A() {
    }

    public void print() {
        System.out.println("A");
    }
}
//File B.java
package b;


import a.*;
public class B extends A {

    B() {
    }

    public void print() {
        System.out.println("B");
    }

    public static void main(String[] args) {
        new B();
    }
}


class normally being declared as public or default accessible.
private class is invalid modifier for the class, actually it doesn't make any sense; a private class should be declared as an inner class.

Monday, 23 May 2016

Method Overriding and Virtual Method Invoking

The purpose of overriding is to allow sub-class to carry out the method in its own preferred way. So the same behaviour may differ from parents to its derivatives. It is an OOP feature that enables a derived class to define a specific implementation of exiting base class to extend its own behaviour. 

Overriding is related to the concept of inheritance; 
A constructor cannot be inherited. A static method is not inherited, but accessible for all instances. A final method cannot be inherited. So we don't need to talk about how to override them. Only non-final instance method that can be inherited, that is overriding about. 

Method overriding reuses the method signature and using the same argument list.  Overridden methods are also synonymous with polymorphic methods. 

The static method cannot be overridden, but hidden; so the concept of overriding is only related to the inheritance concept.  
A final method cannot be overridden. 

A method that can be overridden by a derived class is called a virtual method. Please note that the virtual method is not a Java term, but a term used in OOP domain. A virtual method invocation refers to invoking correct overridden methods. 

parts of a method declaration
non-access modifier  ¶  access modifier  ¶  return type¶  method name ¶ parameter list ¶ exception list¶ 
static/final                  ¶  public, protected
synchronised              ¶  default, private

Correct syntax of overriding methods

method signature exactly the same
method argument: exactly the same
access modifier: can be the same level; or less restrictive access level
Non-access modifier: overriding method can use any non-access modifier. 

Return type: covariant return types.  the overridden method cannot return more generic type; otherwise, the client cannot determine what can be returned from the overridden method.

what is the co-variant principle?
supertype and sub-type

Exceptions that are thrown: for the checked exception, the overridden method can throw the same or none exception; or a subtype of exception that is thrown by the overridden method.  An overriding method can throw any runtime exception, even the overridden method doesn't. 
this is because the un-checked exception is not part of method composition, so it is not checked by the compiler.  

The overriding method can throw no exception, the same exception or subtype of the exception that is thrown by the overridden method. 


It is the reference variable type that dictates which overloaded method will be chosen at the compilation time. 

Can you override all methods from the superclass? 
No. you cannot override static method; you cannot override private method; you cannot override the final method. So you cannot override all methods from the superclass. 

A Method can be overloaded, overridden, or hidden.
A Static method cannot be overridden but hidden. Hidden is about the scope. 
Overloaded is about reuse the method signature, but different parameter list;  
Overriding is about invoking virtual method; 

Why overriding Class Object is important



Overriding has many rules in Java.

Overriding happens only with the concept, Inheritance. Our parents prefer to celebrate a new year in their way; however, for the young generation, they may celebrate in a different way. In such a case, a method inherited can be overridden in the child class. It is called the overridden method, and its counterpart on the child class is called overriding method.

(1) using the same signature.
(2) using the same argument.
(3) allowing co-variant return types. (since Java 1.5)
(4) An overriding method cannot throw a superclass exception, while a constructor of a subclass cannot throw subclass exception(must be the same).

private/final/static methods cannot be overridden.

private cannot be inherited so won't be overridden;
a final method is not allowed to be inherited.
a static method can be hidden, but not overridden.

(5)about access modifier: you cannot define more restrictive access modifier than the method that is going to be overridden.
(6) if the overridden method does not have any throws clause, the overriding method cannot declare any checked exceptions; can throw unchecked. 



Tuesday, 4 September 2007

Abstract Class, Nested Class

Abstract class 

An abstract class is a partially implemented class, so it can not be instantiated. The purpose of the abstract class is to set a place to put common attributes and method pulled out from a category of classes. 

As a creator, you may require some behaviours that derivatives must carry them out. An abstract method is a method signature without implementation, it enforces all non-abstract sub-classes to implement it in their own unique ways. Abstract methods are must be implemented by the sub-classes. If a subclass doesn't want to implement it, it must re-declare this abstract method again in its class body. Only an abstract class can declare abstract methods. Any class contains an abstract method should be declared as an abstract class. 

An abstract class can also have constructors, although an abstract class cannot be instantiated. The purpose of constructors enforces the non-abstract subclasses to initialize as creator designed. The decorator pattern is a good example to explain this, where an abstract decorator enforces the concreate decorator to initialize the association relationship with a decorated instance.  A non-abstract subclass must invoke at least one of a constructor from the abstract superclass.  Otherwise, it gives a compilation error.

An abstract class can implement interfaces, but it doesn't need to implement them. However, its subclasses have to implement them, if the abstract class doesn't implement them yet. 

An abstract class can be extended from a concrete class, for instance, object class is a concrete class, but any abstract must is an extension from it. 

A concrete method could be overridden to be abstract. 

All abstract methods defined in the Abstract classes are enforced to be carried out in the sub-classes. 

Although abstract class cannot be instantiated, it can be used as a data type. An abstract type reference variable can be assigned by all of its non-abstract subclass instances. 

What difference between an abstract class and a concrete class? 

abstract do almost all concrete class can do, but only two differences
  1. an abstract class cannot be instantiated, but a concrete class can.
  2. an abstract method can be defined in abstract class alone, but not in a concrete class. 

Nested Class

A class that is defined within another class, it is a nested class. 

A nested class defined as static is referred to as a static nested class. Nested classes that are not declared as static are referred to as inner classes. 

A nested class can also be defined within methods.  It is referred to as a method local inner class. 
Anonymous inner class is a local class without a name. 












Can Jackson Deserialize Java Time ZonedDateTime

Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...