Every programming language embodies in it a philosophy about how problems should be solved. C reduces all problems to manipulations of memory addresses. Java turns every problem into a set of interacting objects. JavaScript summons Shub-Niggurath, the black goat of the woods with a thousand young, to eat the eyes of developers.

Just following the logic of a language can send you a long way to getting good results. Popular languages were designed by smart people, who work through many of the problems you might encounter when building a program with their tools. That doesn’t mean that you can’t take things a bit too far and misapply that philosophy, though.

Take this code, sent to us by “Kogad”. Their co-worker understood that objects and interfaces were fundamental to Java programming, so when presented with the challenge of three conditional statements, they created this:

package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;

public interface ProcesSpecification {
        boolean isSatisfiedBy(CustomerRequest req);
}
//--------------
package com.initrode.account.framework.process.specification;

public abstract class CompositeProcesSpecification implements ProcesSpecification {

        public ProcesSpecification and(ProcesSpecification specification){
                return new AndProcesSpecification(this, specification);
        }

        public ProcesSpecification or(ProcesSpecification specification){
                return new OrProcesSpecification(this, specification);
        }

        public ProcesSpecification not(ProcesSpecification specification){
                return new NotProcesSpecification(specification);
        }

}
//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;

public class NotProcesSpecification extends CompositeProcesSpecification {

        private ProcesSpecification spec;

        public NotProcesSpecification(ProcesSpecification specification) {
                spec = specification;
        }

        @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return !spec.isSatisfiedBy(req);
        }

}

//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;

public class AndProcesSpecification extends CompositeProcesSpecification {
        private ProcesSpecification specOne;
        private ProcesSpecification specTwo;

        public AndProcesSpecification(ProcesSpecification specificationOne, ProcesSpecification specificationTwo) {
                specOne = specificationOne;
                specTwo = specificationTwo;
        }

        @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return specOne.isSatisfiedBy(req) && specTwo.isSatisfiedBy(req);
        }

}
//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;


public class OrProcesSpecification extends CompositeProcesSpecification {
        private ProcesSpecification specOne;
        private ProcesSpecification specTwo;

        public OrProcesSpecification(ProcesSpecification specificationOne, ProcesSpecification specificationTwo) {
                specOne = specificationOne;
                specTwo = specificationTwo;
        }

        @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return specOne.isSatisfiedBy(req) || specTwo.isSatisfiedBy(req);
        }

}
//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;
import com.initrode.account.framework.process.CustomerType;

public class TypeOneProcesSpecification extends CompositeProcesSpecification {

        @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return null != req && CustomerType.ONE == req.getType();
        }

}

//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;
import com.initrode.account.framework.process.CustomerType;

public class TypeTwoProcesSpecification extends CompositeProcesSpecification {

        @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return null != req && CustomerType.TWO == req.getType();
        }

}
//--------------
package com.initrode.account.framework.process.specification;

import com.initrode.account.framework.process.CustomerRequest;

public class VerifyProcessSpecification extends CompositeSpecification
    @Override
        public boolean isSatisfiedBy(CustomerRequest req) {
                return req.hasVerificationCode();
        }
}

//--------------
// Usage:

public class ActionOne {
        private ProcesSpecification procesSpec;

        @PostConstruct
        protected void postInitialize() {
                setProcesSpecification(new VerifyProcessSpecification().and(new TypeOneProcesSpecification()));
        }

    @Override public boolean canHandle(CustomerRequest req) {
        return procesSpec.isSatisfiedBy(req);
    }

    @Override
    void doAction(...);
}

public class ActionTwo {
        private ProcesSpecification procesSpec;

        @PostConstruct
        protected void postInitialize() {
                setProcesSpecification(new VerifyProcessSpecification().and(new TypeTwoProcesSpecification()));
        }

    @Override public boolean canHandle(CustomerRequest req) {
        return procesSpec.isSatisfiedBy(req);
    }

    @Override
    void doAction(...);
}

public class ActionThree {
        private ProcesSpecification procesSpec;

        @PostConstruct
        public void postInitialize() {
                procesSpec = new NotProcesSpecification(new VerifyProcessSpecification().and(
                                new TypeOneProcesSpecification().or(new TypeTwoProcesSpecification())));
        }

    @Override public boolean canHandle(CustomerRequest req) {
        return procesSpec.isSatisfiedBy(req);
    }

    @Override
    void doAction(...);
}

This is certainly Peak Java™. It’s… extensible, at least. Not that you’d want to. “Kogad” replaced this masterpiece with a much simpler, if less extensible, chain of conditionals that were also more closely mapped to their actual requirements.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!