設計模式是前人開發經驗的總結,可是隨着Java語言的發展,不少設計模式有了新的表達方式。java
尤爲是Lambda表達式的出現。下面介紹幾種使用Lambda重構的設計模式 。設計模式
策略模式,模板方法,觀察者模式,責任鏈模式,工廠模式。app
策略模式 簡言之:一個接口,多種實現。使用時進行選擇。ide
不使用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重構後: this
@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"); } }
基於抽象方法,在抽象類實現 詳見本博客:http://www.javashuo.com/article/p-ycvnivyt-kz.htmlspa
/** * 在線銀行 */ abstract class OnlineBanking{ /** * 模板方法 */ public processCustomer(int id){ Customer c = Datebase.getCustomerWithID(id); makeCustomerHappy(c); } /** * 讓上帝爽 */ abstract void makeCustomerHappy(Customer c ); }
使用Lambda重構後: .net
/** * 在線銀行 */ @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表達式後code
// 有沒有這個函數接口聲明都能使用 我只是爲了體現 它的函數接口特性 @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擴展性不強,其實剛開始寫代碼用這種模式寫不利於擴展。