JDK1.8 使用Lambda重构设计模式

设计模式是前人开发经验的总结,但是随着Java语言的发展,很多设计模式有了新的表达方式。

尤其是Lambda表达式的出现。下面介绍几种使用Lambda重构的设计模式 。

策略模式,模板方法,观察者模式,责任链模式,工厂模式。

策略模式

策略模式 简言之:一个接口,多种实现。使用时进行选择。

不使用Lambda重构

public interface ValidationStrategy {
    boolean execute(String s);
}
public class IsAllLowerCase implements ValidationStrategy {
  
    @Override
    public boolean execute(String s) {
        return s.matches("[a-z]+");
    }
    
}
public class IsNumeric implements ValidationStrategy {
  
    @Override
    public boolean execute(String s) {
        return s.matches("\\d+");
    }
    
}
public class Validator {

    private final ValidationStrategy strategy;

    public Validator(ValidationStrategy strategy) {
        this.strategy = strategy;
    }

    public boolean validate(String s) {
        return strategy.execute(s);
    }

    public static void main(String[] args) {
        Validator numValidator = new Validator(new IsNumeric());
        numValidator.validate("aaaa");
    }
}

使用Lambda重构后: 

@FunctionalInterface
public interface ValidationStrategy {
    boolean execute(String s);
}
public class Validator {

    private final ValidationStrategy strategy;

    public Validator(ValidationStrategy strategy) {
        this.strategy = strategy;
    }

    public boolean validate(String s) {
        return strategy.execute(s);
    }

    public static void main(String[] args) {
        boolean validate = new Validator(s -> s.matches("[a-z]+")).validate("aaaa");
    }
}

模板方法

基于抽象方法,在抽象类实现 详见本博客:https://my.oschina.net/u/3418748/blog/1617291

 /**
  *	在线银行
  */
abstract class OnlineBanking{
   /**
	* 模板方法
	*/
	public processCustomer(int id){
		Customer c = Datebase.getCustomerWithID(id);
		makeCustomerHappy(c);
	}

   /**
	* 让上帝爽
	*/
	abstract void makeCustomerHappy(Customer c );
}

使用Lambda重构后: 

 /**
  *	在线银行
  */
@Service
public class OnlineBanking{
   /**
	* 模板方法
	*/
	public processCustomer(int id,Consumer<Customer> makeCustomerHappy){
		Customer c = Datebase.getCustomerWithID(id);
		makeCustomerHappy.accept(c);
	}
}

// 使用方式
public class Test{
	@Autowried
	OnlineBanking onlineBanking;

	public void test{
	onlineBanking.processCustomer(123,(Consumer c) -> {
		// 做一些羞羞的事
	})
	}
}

观察者模式

不使用Lambda表达且最简单一种实现

public interface Observer {
    void notify(String tweet);
}
/**
 * 《纽约时报》
 * 
 * @author lien6o
 *
 */
public class NYTimes implements Observer {

    @Override
    public void notify(String tweet) {
        if (tweet != null && tweet.contains("money")) {
            System.err.println("Breaking news in NY" + tweet);
        }
    }

}
/**
 * 《卫报》
 * 
 * @author lien6o
 *
 */
public class Guardian implements Observer {

    @Override
    public void notify(String tweet) {
        if (tweet != null && tweet.contains("queen")) {
            System.err.println("Yet another news in London..." + tweet);
        }
    }

}
public interface Subject {
    void registerObserver(Observer o);
    void notifyObserver(String tweet);
}
public class Feed implements Subject {
    private final List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer o) {
        this.observers.add(o);
    }

    @Override
    public void notifyObserver(String tweet) {
        this.observers.forEach(o -> o.notify(tweet));
    }

    public static void main(String[] args) {
        Feed feed = new Feed();
        feed.registerObserver(new NYTimes());
        feed.registerObserver(new Guardian());
        feed.notifyObserver("The queen says her favorite blog is the one you see");
    }
}

 使用Lambda表达式后

// 有没有这个函数接口声明都能使用 我只是为了体现 它的函数接口特性
@FunctionalInterface
public interface Observer {
    void notify(String tweet);
}
public class Feed implements Subject {
    private final List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer o) {
        this.observers.add(o);
    }

    @Override
    public void notifyObserver(String tweet) {
        this.observers.forEach(o -> o.notify(tweet));
    }

    public static void main(String[] args) {
        Feed feed = new Feed();
        // 取消了Observer的实现类  在使用时直接使用 
        // 简单实现可以在用lambda表达式这样使用,复杂的不建议这样操作,不能解耦。反而适得其反
        feed.registerObserver(tweet -> {
            if (tweet != null && tweet.contains("money")) {
                System.err.println("Breaking news in NY" + tweet);
            }
        });
        feed.notifyObserver("The queen says her favorite blog is the one you see");
    }
}

个人感觉在观察者模式使用意义不大。 

责任链模式

这种模式是通过定义一个代表处理对象的抽象类来具体实现的,在抽象类中会定义一个字段来记录后续对象。一旦对象完成它的工作,处理对象就会将它的工作换交给它的后继。

public abstract class ProcessingObject<T> {
    
    protected ProcessingObject<T> successor;

    public void setSeccessor(ProcessingObject<T> successor) {
        this.successor = successor;
    }

    abstract protected T handleWork(T input);

    public T handle(T input) {
        T r = handleWork(input);
        if (successor != null) {
            return successor.handle(r);
        }
        return r;
    }
}
public class HeaderTextProcessing extends ProcessingObject<String> {

    @Override
    protected String handleWork(String text) {
        return "From Raoul,Mario and Alan:" + text;
    }

}
public class SpellCkeckerProcessing extends ProcessingObject<String> {

    @Override
    protected String handleWork(String text) {
        return text.replace("labda", "lambda");
    }

}
 public static void main(String[] args) {
        HeaderTextProcessing p1 = new HeaderTextProcessing();
        SpellCkeckerProcessing p2 = new SpellCkeckerProcessing();
        p1.setSeccessor(p2);
        String handle = p1.handle("Aren't labdas readlly sexy!!");
        System.err.println(handle);
    }

使用Lambda表达式

  public static void main(String[] args) {
        // UnaryOperator t -> t; 一元表达式
        UnaryOperator<String> p1 = text -> "From Raoul,Mario and Alan:" + text;
        UnaryOperator<String> p2 = text -> text.replace("labda", "lambda");
        // andThen() return (T t) -> after.apply(apply(t))
        Function<String, String> pipeline = p1.andThen(p2);
        String result = pipeline.apply("Aren't labdas readlly sexy!!");
        System.err.println(result);
    }

 使用Lambda构造链接。很赞!

工厂模式

    public static Product createProduct(String name) {
        switch (name) {
        case "loan":
            return new Loan();
        case "stock":
            return new Stock();
        default:
            throw new RuntimeException("No such product " + name);
        }
    }
  public static void main(String[] args) {
        Stock stock = (Stock) ProductFactory.createProduct("stock");
    }

使用Lambda表达式

  final static Map<String, Supplier<Product>> map = new HashMap<>();
    static {
        map.put("loan", Loan::new);
        map.put("stock", Stock::new);
    }

    public static void main(String[] args) {
        Product product = map.get("loan").get();
    }

重构后对于简单参数映射对象使用lambda还不错,但是多个参数lambda扩展性不强,其实刚开始写代码用这种模式写不利于扩展。

猜你喜欢

转载自my.oschina.net/u/3418748/blog/1640365