I made this password generator I'll use in a simple Android App.I want that it generates a password using a truly random number source, but I don't have idea how to do it by now, so a let a seed parameter to generator class that will be created by that numbers source.I used the decorator pattern to compose the source from which the chars will be picked up. So if I want a password in which the chars will be picked up from a source of numbers and lower case letters I will decorate it with NumericDomainRange and LowercaseDomainRange, but there is no warranty that the password generated will be composed of number and letters.  It must calculates the password entropy based on some algorithms, I have not implemented anything yet. Please, review its overall design.root package:public class GenPass {    public Password generate(int size, long seedFromTrulyRandomNumbersSource, DomainRange domainRange) {        PasswordGenerator passwordGenerator = new SequencialPasswordGenerator(seedFromTrulyRandomNumbersSource);        return passwordGenerator.generate(size, domainRange.getDomain());    }    public static void main(String[] args) {        Password generatedPassword = new GenPass().generate(20, System.currentTimeMillis(), buildDomainRange());        generatedPassword.setStrengthCalculator(getStrengthCalculator());        System.out.println(generatedPassword);    }    private static PasswordEntropyStrengthCalculator getStrengthCalculator() {        return new PasswordEntropyStrengthCalculator();    }    private static DomainRange buildDomainRange() {        return new LowercaseDomainRange(new SpecialCharsDomainRange(new UppercaseDomainRange(new NumericDomainRange(new BaseDomainRange()))));    }}password package:public class Password implements HasStrength {    private StrengthCalculator strengthCalculator = StrengthCalculator.EMPTY;    private String password;    public Password(String password) {        this.password = password;    }    @Override    public void setStrengthCalculator(StrengthCalculator strengthCalculator) {        this.strengthCalculator = strengthCalculator;    }    @Override    public double getStrength() {        return strengthCalculator.calculate(password);    }    @Override    public String toString() {        return Password{ +                strengthCalculator= + getStrength() +                , password=' + password + '\'' +                '}';    }}public interface HasStrength {    void setStrengthCalculator(StrengthCalculator strengthCalculator);    double getStrength();}public class PasswordEntropyStrengthCalculator implements StrengthCalculator {    @Override    public double calculate(String password) {        //TODO: to be implemented        return 20;    }}public interface StrengthCalculator {    double calculate(String password);    StrengthCalculator EMPTY = new StrengthCalculator() {        @Override        public double calculate(String password) {            return -1;        }    };}generator package:public interface PasswordGenerator {    Password generate(int size, String domain);}public abstract class AbstractPasswordGenerator implements PasswordGenerator {    private Random random;    public AbstractPasswordGenerator(long seed) {        this.random = new Random(seed);    }    protected int getRandomInt(int bound) {        return random.nextInt(bound);    }}public class SequencialPasswordGenerator extends AbstractPasswordGenerator {    public SequencialPasswordGenerator(long seed) {        super(seed);    }    @Override    public Password generate(int size, String domain) {        StringBuilder sb = new StringBuilder();        for (int i = 0; i < size; i++) {            int r = super.getRandomInt(domain.length());            sb.append(domain.charAt(r));        }        return new Password(sb.toString());    }}domainrange package:public interface DomainRange {    String getDomain();}public class BaseDomainRange implements DomainRange {    @Override    public String getDomain() {        return ;    }}public abstract class DomainRangeDecorator implements DomainRange {    private DomainRange domainRange;    public DomainRangeDecorator(DomainRange domainRange) {        this.domainRange = domainRange;    }    @Override    public String getDomain() {        return domainRange.getDomain();    }}public class LowercaseDomainRange extends DomainRangeDecorator {    public LowercaseDomainRange(DomainRange domainRange) {        super(domainRange);    }    @Override    public String getDomain() {        return super.getDomain() + Charset.ALPHA.getDomainRange();    }}public class NumericDomainRange extends DomainRangeDecorator {    public NumericDomainRange(DomainRange domainRange) {        super(domainRange);    }    @Override    public String getDomain() {        return super.getDomain() + Charset.DIGITS.getDomainRange();    }}public class SpecialCharsDomainRange extends DomainRangeDecorator {    public SpecialCharsDomainRange(DomainRange domainRange) {        super(domainRange);    }    @Override    public String getDomain() {        return super.getDomain().concat(Charset.SPECIAL.getDomainRange());    }}public class UppercaseDomainRange extends DomainRangeDecorator {    public UppercaseDomainRange(DomainRange domainRange) {        super(domainRange);    }    @Override    public String getDomain() {        return super.getDomain().concat(Charset.ALPHA.getDomainRange().toUpperCase());    }}public enum Charset {    DIGITS(0123456789), ALPHA(abcdefghijklmnopqrstuvxz), SPECIAL(!#$%&()*+,-./:;<=>?@[]_|~);    private String domainRange;    Charset(String domainRange) {        this.domainRange = domainRange;    }    public String getDomainRange() {        return domainRange;    }}
Password generator using Decorator Pattern
java;object oriented;design patterns