public double totalizar() {
double total = 0.0;
List<Factura> facturas = servicio.obtenerFacturas();
for (Factura f : facturas) {
total += f.valor();
}
return total;
}
public double totalizar() {
double total = 0.0;
List<Factura> facturas = servicio.obtenerFacturas();
for (Factura f : facturas) {
if (f.getContratante().equals("Google") {
total += f.valor();
}
}
return total;
}
public double totalizar() {
double total = 0.0;
List<Factura> facturas = servicio.obtenerFacturas();
YearMonth ahora = YearMonth.now();
YearMonth hace2Meses = ahora.minusMonths(2);
for (Factura f : facturas) {
if (f.getContratante().equals("Google") && f.esDespués(hace2Meses)) {
total += f.valor();
}
}
return total;
}
public interface Predicate<T> {
boolean test(T t);
}
public double totalizar(final Predicate<Function> predicado) {
double total = 0.0;
List<Factura> facturas = servicio.obtenerFacturas();
for (Factura f : facturas) {
if (predicado.test(f)) {
total += f.valor();
}
}
return total;
}
double total = totalizar(new Predicate<Factura>() {
@Override
public boolean test(Factura factura) {
return factura.getContratante().equals("Google");
}
});
public static final Predicate<Factura> ES_GOOGLE =
new Predicate<Factura>() {
@Override
public boolean test(Factura factura) {
return factura.getContratante().equals("Google");
}
};
* * *
double total = totalizar(ES_GOOGLE);
public interface Command {
public void run() throws DrawException;
}
public abstract class DrawingCommand
implements Command {
private Canvas canvas;
public DrawingCommand(final Canvas canvas) {
this.canvas = canvas;
}
}
public class DrawLine
extends DrawingCommand {
private Point p1;
private Point p2;
public DrawLine(Canvas canvas, Point p1, Point p2) {
super(canvas);
this.p1 = p1;
this.p2 = p2;
}
public void run() throws DrawException {
// dibuja una línea en el canvas
}
}
public class RectangleLine
extends DrawingCommand {
private Point p1;
private Point p2;
public DrawLine(Canvas canvas, Point p1, Point p2) {
super(canvas);
this.p1 = p1;
this.p2 = p2;
}
public void run() throws DrawException {
// dibuja un rectángulo
}
}
public abstract class BucketFill
extends DrawingCommand {
private Point p1;
private Color color;
public DrawLine(Canvas canvas, Point p1, Color color) {
super(canvas);
this.p1 = p1;
this.color = color;
}
public void run() throws DrawException {
// usa la cubeta
}
}
public class DrawingApp {
public void execute(Command command) {
try {
command.run();
} catch (DrawException e) {
// maneja de una manera consistente
// los errors de los comandos
}
}
}
public interface Command {
void run() throws DrawException;
void undo();
}
public abstract class BucketFill
extends DrawingCommand {
private Point p1;
private Color before;
private Color color;
public BucketFill(Canvas canvas, Point p1, Color color) {
super(canvas);
this.before = canvas.getColor(p1);
this.p1 = p1;
this.color = color;
}
public void run() throws DrawException {
run(p1, color);
}
private void run(Point p1, Color color) {
// pinta a p1 con el color dado
// se llama recursivamente para pintar
// los vecinos
}
public void undo() {
run(p1, before);
}
}
public class DrawingApp {
private Deque<Command> cola = new ArrayDeque<>();
public void execute(Command command) {
try {
cola.add(command);
command.run();
} catch (DrawException e) {
// maneja de una manera consistente
// los errors de los comandos
}
}
public void undo() {
Command último = cola.pop();
último.undo();
}
}
public interface AlarmaListener {
void actuar();
}
public class Luces implements AlarmaListener {
public void actuar() {
System.out.println("encender luces");
}
}
* * *
public class Puertas implements AlarmaListener {
public void actuar() {
System.out.println("puertas cerradas");
}
}
public class SistemaCentral {
private List<AlarmaListener> listeners =
new ArrayList<>();
public void registrar(AlarmListener listener) {
listeners.add(listener);
}
public void activarAlarma() {
for (AlarmaListener listener : listeners) {
listener.actuar();
}
}
}
public static void main(String[] args) {
Luces luces = new Luces();
Puertas puertas = new Puertas();
SistemaCentral sistema = new SistemaCentral();
sistema.registrar(luces);
sistema.registrar(puertas);
sistema.sonarAlarma();
// luces encendidas
// puertas cerradas
}
public class Empresa implements AlarmaListener {
public void actuar() {
System.out.println("notificando empresa");
}
}
public static void main(String[] args) {
AlarmaListener luces = new Luces();
AlarmaListener puertas = new Puertas();
AlarmaListener empresa = new Empresa();
SistemaCentral sistema = new SistemaCentral();
sistema.registrar(luces);
sistema.registrar(puertas);
sistema.registrar(empresa);
sistema.sonarAlarma();
// luces encendidas
// puertas cerradas
// notificando empresa
}
public class Avatar {
public void disparar() {
// esto debe poder
// cambiar en tiempo real
}
}
/**
* Esta clase encapsula lo que puede
* cambiar de la clase Avatar
*/
public interface Arma {
void disparar();
}
public class Blaster implements Arma {
public void disparar() {
System.out.println("BLASTER");
}
}
* * *
public class Laser implements Arma {
public void disparar() {
System.out.println("LASER");
}
}
* * *
public class Lanzallamas implements Arma {
public void disparar() {
System.out.println("LANZALLAMAS");
}
}
public class Avatar {
private Arma arma;
public Avatar() {
this.arma = new Blaster();
}
// un "setter" es una opción
public void cambiarArma(final Arma arma) {
this.arma = arma;
}
public void disparar() {
arma.disparar();
}
}
public static void main(String[] args) {
Avatar avatar = new Avatar();
avatar.disparar(); // BLASTER
avatar.cambiarArma(new Laser());
avatar.disparar(); // LASER
}
public enum Arma {
BLASTER {
public void disparar() {
System.out.println("BLASTER");
}
}, LASER {
public void disparar() {
System.out.println("LASER");
}
}, LANZALLAMAS {
public void disparar() {
System.out.println("LANZALLAMAS");
}
};
public abstract void disparar();
}
public static void main(String[] args) {
Avatar avatar = new Avatar();
avatar.disparar(); // BLASTER
avatar.cambiarArma(Arma.LASER);
avatar.disparar(); // LASER
}
public interface Estado {
// el estado puede cambiar
// después de llamar uno
// de los métodos!
Estado insertarMoneda();
Estado presionarBotón();
}
public class MonedaInsertada implements Estado {
@Override
public Estado insertarMoneda() {
System.out.println("Moneda ya insertada. Ignorando");
return this; // estado no cambia
}
@Override
public Estado presionarBotón() {
System.out.println("Producto en la bandeja");
return new Vacía(); // el estado cambia
}
}
public class Vacía implements Estado {
@Override
public Estado insertarMoneda() {
System.out.println("Moneda recibida.");
return new MonedaInsertada(); // estado cambia
}
@Override
public Estado presionarBotón() {
System.out.println("No se ha insertado una moneda");
return this; // estado no cambia
}
}
public class MáquinaDispensadora {
private Estado actual = new Vacía();
public void insertarMoneda() {
actual = actual.insertCoin();
}
public void presionarBotón() {
actual = actual.pressButton();
}
}
public static void main(String[] args) {
MáquinaDispensadora máquina =
new MáquinaDispensadora();
máquina.insertarMoneda(); // recibida
máquina.presionarBotón(); // producto
máquina.presionarBotón(); // ignorado
máquina.insertarMoneda(); // recibida
máquina.insertarMoneda(); // ignorada
máquina.presionarBotón(); // producto
}
Cada método que puede variar tendría un if por cada personalización.
Si tenemos n maneras distintas
de hacer el método tenemos n if's
public abstract class Giro {
public final void realizar(Transacción transacción) {
try {
validar(transacción.getUsuario());
autorizar(transacción.getTarjeta());
cobrar(transacción);
auditar(transacción);
} catch (TransacciónException e) {
revertir(transacción);
}
}
private void validar(Usuario usuario) {
// ir a la base de datos y verificar
// que usario no tiene restricciones
}
protected abstract void autorizar(Tarjeta tarjeta);
protected abstract void cobrar(Transacción trx);
protected abstract void auditar(Transacción trx);
protected abstract void revertir(Transacción trx);
}
public final class GiroNacional extends Giro {
protected void autorizar(Tarjeta tarjeta) {
// intentar cobrar $0
}
protected void cobrar(Transacción trx) {
// se realiza el cobro al proveedor nacional
}
protected void auditar(Transacción trx) {
// se guarda la cédula del usuario
// el número de la tarjeta, el monto y la fecha
}
protected void revertir(Transacción trx) {
// se revierten los pasos
}
}
public final class GiroInternacional extends Giro {
protected void autorizar(Tarjeta tarjeta) {
// intentar cobrar $.5
}
protected void cobrar(Transacción trx) {
// se realiza el cobro al proveedor
// internacional por el monto menos $.5
}
protected void auditar(Transacción trx) {
// el nombre del usuario, número de la tarjeta,
// el monto, la fecha y el destinatario
}
protected void revertir(Transacción trx) {
// se revierten los pasos
}
}
public abstract class MegaNav {
private PageFetcher fetcher;
public MegaNav(PageFetcher fetcher) {
this.fetcher = fetcher;
}
public final NavMenu build(User user) {
Item featured = getFeatured(user);
List<Link> headers = getHeaders(user);
List<Column> columns = new ArrayList<>(6);
for (Link link : headers) {
Column c = new Column(
link, fetcher.subPages(link.getUrl());
columns.add(c);
}
return new NavMenu(features, columns);
}
protected Item getFeatured(User user);
protected List<Column> getHeaders(User user);
}
public final class EmpleadoMegaNav extends MegaNav {
public EmpleadoMegaNav(PageFetcher fetcher) {
super(fetcher);
}
@Override
protected Item getFeatured(User user) {
// obtener la última noticia del departamento
// al que pertenece el usuario
}
@Override
protected List<Column> getHeaders(User user) {
// Los cabezotes son Compañía, Departamento,
// Oficina, Recursos Humanos
}
}
public final class LíderMegaNav extends MegaNav {
public LíderMegaNav(PageFetcher fetcher) {
super(fetcher);
}
@Override
protected Item getFeatured(User user) {
// Obtener la próxima reunión de equipo
}
@Override
protected List<Column> getHeaders(User user) {
// Los cabezotes son Compañía, Empleados Área
// Oficina, Recursos Humanos
}
}
public final class AccionistaMegaNav extends MegaNav {
public AccionistaMegaNav(PageFetcher fetcher) {
super(fetcher);
}
@Override
protected Item getFeatured(User user) {
// Obtener la próxima reunión de accionistas
}
@Override
protected List<Column> getHeaders(User user) {
// Los cabezotes son Compañía, Oficina,
// Recursos Humanos, Información Financiera
}
}
public final class GiroFactory {
public static Giro(País país) {
if (país.esNacional()) {
return new GiroNacional();
}
return new GiroInternacional();
}
}
public final class MegaNavFactory {
public static MegaNav(PageFetcher fetcher, User user) {
switch(user.getType()) {
case EMPLEADO:
return new EmpleadoMegaNav(fetcher);
case LÍDER:
return new LíderMegaNav(fetcher);
case ACCIONISTA:
return new AccionistaMegaNav(fetcher);
default:
throw new AssertionError(
"Tipo de Usuario no esperado: " + type);
}
}
}