hi.cosmonaut
hi.cosmonaut

Reputation: 163

Clean Archtecture. Understanding of scheme

can you help me to understand the next thing right? So, I read Clean Architecture by R.Martin and there are many schemes.

Picture 1:

picture 1

My implementation:

Billing.java

public class Billing {

    public Billing(){

        //creating of licenses
        License personalLicense = new PersonalLicense();
        License businessLicense = new BusinessLicense();

        //method using
        personalLicense.calcFee();
        businessLicense.calcFee();
    }
}

License.java

public interface License {
    public void calcFee();
}

PersonalLicense.java

public class PersonalLicense implements License {

    public PersonalLicense(){
        //constructor implementation here
    }

    @Override
    public void calcFee(){
        //method implementation here
    }
}

BusinessLicense.java

public class BusinessLicense implements License {

    //private ? users - Unknown type just for example

    @Override
    public BusinessLicense(){
        //constructor implementation here
    }

    public void calcFee(){
        //method implementation here
    }
}

Picture 2: enter image description here

My implementation:

U1Ops.java

public interface U1Ops{
    public void op1();
}

U2Ops.java

public interface U2Ops{
    public void op2();
}

U3Ops.java

public interface U3Ops{
    public void op3();
}

OPS.java

public class OPS implements U1Ops, U2Ops, U3Ops{
    public OPS(){ ... }

    @Override
    public void op1() { ... }

    @Override
    public void op2() { ... }

    @Override
    public void op3() { ... }
}

User1.java

public class User1 {
    public User1(){
        OPS u1Ops = new U1Ops();
        u1Ops.op1();
    }
}

User2.java

public class User2 {
    public User2(){
        OPS u2Ops = new U2Ops();
        u2Ops.op2();
    }
}

User3.java

public class User3 {
    public User3(){
        OPS u3Ops = new U3Ops();
        u3Ops.op3();
    }
}

Picture 3: enter image description here

My implementation:

Permissions.java

public class Permissions{

    public Permissions() { ... }

    public classMethod() { ... }
}

User1.java

public class User1 {
    public User1(){
        Permissions p = new Permissions();
        p.classMethod();
    }
}

UNDERLINE IMPLEMENTATION

IPermissions.java

public interface IPermissions{
    public void interfaceMethod()();
}

Permissions.java

public class Permissions implements IPermissions{

    public Permissions() { ... }

    @Override
    public interfaceMethod() { ... }
}

User2.java

public class User2 {
    public User2(){
        IPermissions p = new Permissions();
        p.interfaceMethod();
    }
}

The common detail of these schemes is: enter image description here

Main.java

public class Main {
    public Main(){
        ITest t = new Test();
        t.someMethod();
    }
}

ITest.java

public interface ITest{
    public void someMethod()();
}

Test.java

public class Test implements ITest{

    public Test() { ... }

    @Override
    public someMethod() { ... }
}

Do I understand these schemes right?

Upvotes: 1

Views: 137

Answers (1)

Andrei Nazarov
Andrei Nazarov

Reputation: 83

Picture 1:

License, PersonalLicense, BusinessLicense is ok, Billing must be like that:

public class Billing {
    private Lisense license;

    public Billing(License license){
        this.license = license;
    }

    public void pay(){
       // some code
       this.license.calcFee();
       // some code
    }

    public void setLicense(License license){
        this.license = license;
    }
}

It's look like Strategy pattern, which lets you define a family of algorithms(License), put each of them into a separate class(PersonalLicense,BusinessLicense), and make their objects interchangeable. Main feature is that Billing class only know that it has some License object, which can calcFee, without knowing a specific implementation. Later, for supporting new license types, you will create new implementations of License and won't modify Billing.

Picture 2:

User1, User2, User3, must be something like that, with corresponding U*Ops:

public class User1 {
    private U1Ops u1Ops;
    public User1(U1Ops u1Ops){
        this.u1Ops = u1Ops;
    }
}

// usage of classes
OPS ops = new OPS();
User1 user1 = new User1(ops);
User2 user2 = new User2(ops);

Looks like example of interface segregation principle from SOLID it states that no client(User1, User2, User3) should be forced to depend on methods it does not use(User1 only need op1()).

Picture 3:

As in previous examples, association must be implemented with User instance field. Those diagrams demonstrates Dependency inversion principle (upper - bad practice, underline - good practice). According it, User must know only about some abstract Permissions interface and not about specific implementation, Permissions class know only about Permissions interface which it implements. With usage of this principle, Entities module create their own abstractions level(API) - Permissions interface and Authorizer using it. Related term to it is Dependency injection with commonly used in java frameworks (e.g. Spring Framework) for low coupling between modules

Upvotes: 2

Related Questions