规范模式【其他模式】

规范模式

@Slf4j
public class Specification {
    /**
     * 规范模式:
     * Specification pattern separates the statement of how to match a candidate,
     * from the candidate object that it is matched against.
     * As well as its usefulness in selection,
     * it is also valuable for validation and for building to order.
     *  规范模式将如何匹配目标的代码从匹配目标中分离出来。
     *  规范模式在选择、验证和构建顺序时都很有用。
     */
    @Test
    public void all() {
        final List<Creature> creatures = Arrays.asList(new Goblin(), new Dragon(), new Shark(), new KillerBee());

        log.info("Find all walking creatures");
        final List<Creature> walkingCreatures = creatures.stream().filter(MovementSelector.of(Movement.WALKING))
                .collect(Collectors.toList());
        walkingCreatures.stream().forEach(c -> log.info(c.toString()));

        log.info("Find all dark creatures");
        final List<Creature> darkCreatures = creatures.stream().filter(ColorSelector.of(Color.DARK))
                .collect(Collectors.toList());
        darkCreatures.stream().forEach(c -> log.info(c.toString()));

        log.info("Find all red and flying creatures");
        final List<Creature> redAndFlyingCreatures = creatures.stream()
                .filter(ColorSelector.of(Color.RED).and(MovementSelector.of(Movement.FLYING)))
                .collect(Collectors.toList());
        redAndFlyingCreatures.stream().forEach(c -> log.info(c.toString()));
    }
}

interface Creature {
    String getName();

    Size getSize();

    Movement getMovement();

    Color getColor();
}

@AllArgsConstructor
@Getter
enum Color {
    DARK("dark"), LIGHT("light"), GREEN("green"), RED("red");
    private String title;
}

@AllArgsConstructor
@Getter
enum Movement {
    WALKING("walking"), SWIMMING("swimming"), FLYING("flying");
    private String title;
}

@AllArgsConstructor
@Getter
enum Size {
    SMALL("small"), NORMAL("normal"), LARGE("large");
    private String title;
}

@AllArgsConstructor
@ToString
abstract class AbstractCreature implements Creature {
    private final String name;
    private final Size size;
    private final Movement movement;
    private final Color color;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Size getSize() {
        return size;
    }

    @Override
    public Movement getMovement() {
        return movement;
    }

    @Override
    public Color getColor() {
        return color;
    }
}

class Dragon extends AbstractCreature {
    public Dragon() {
        super("Dragon", Size.LARGE, Movement.FLYING, Color.RED);
    }
}

class Goblin extends AbstractCreature {

    public Goblin() {
        super("Goblin", Size.SMALL, Movement.WALKING, Color.DARK);
    }
}

class KillerBee extends AbstractCreature {

    public KillerBee() {
        super("KillerBee", Size.SMALL, Movement.FLYING, Color.LIGHT);
    }
}

class Shark extends AbstractCreature {

    public Shark() {
        super("Shark", Size.NORMAL, Movement.SWIMMING, Color.LIGHT);
    }
}

@Value(staticConstructor = "of")
class ColorSelector implements Predicate<Creature> {
    private final Color c;

    @Override
    public boolean test(Creature t) {
        return t.getColor().equals(c);
    }
}

@Value(staticConstructor = "of")
class MovementSelector implements Predicate<Creature> {
    private final Movement m;

    @Override
    public boolean test(Creature t) {
        return t.getMovement().equals(m);
    }
}

@Value(staticConstructor = "of")
class SizeSelector implements Predicate<Creature> {
    private final Size s;

    @Override
    public boolean test(Creature t) {
        return t.getSize().equals(s);
    }
}
原文地址:https://www.cnblogs.com/zhuxudong/p/10224746.html