设计模式是前人开发经验的总结,但是随着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扩展性不强,其实刚开始写代码用这种模式写不利于扩展。