java编程思想中的设计模式
2017-12-16 12:51
351 查看
1命令设计模式
命令设计模式首先需要一个只有单一方法的接口,然后从该接口实现具有各自不同的行为的多个子类。接下来,程序员就可以构造命令对象,并在需要的时候使用它们:
2职责链设计模式
程序员以多种不同的方式来解决一个问题,然后将它们链接起来。当一个请求到来时,它遍历这个链,直到链中的某个解决方案能够处理该请求。
下面的代码中,每一次尝试可以看作一个策略。
3模板方法
一些功能在基类中实现,并且其一个或多个抽象方法在派生类中定义,这种结构在设计模式中称为模板方法。
例如下面的PairManager类:
4策略设计模式
Delayed接口有一个方法为getDelay(TimeUnit unit),这个方法强制我们去使用TimeUnit类,可以很容易地转换单位而无需作任何声明,这是策略设计模式的一个简单示例,在这种模式中,算法的一部分是作为参数传递进来的。
5代理
代理是为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。
package com;//: typeinfo/SimpleProxyDemo.java
interface Interface {
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface {
public void doSomething() { System.out.println("doSomething"); }
public void somethingElse(String arg) {
System.out.println("somethingElse " + arg);
}
}
class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
public void doSomething() {
System.out.println("SimpleProxy doSomething");
proxied.doSomething();
}
public void somethingElse(String arg) {
System.out.println("SimpleProxy somethingElse " + arg);
proxied.somethingElse(arg);
}
}
class SimpleProxyDemo {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
} /* Output:
doSomething
somethingElse bonobo
SimpleProxy doSomething
doSomething
SimpleProxy somethingElse bonobo
somethingElse bonobo
*///:~
命令设计模式首先需要一个只有单一方法的接口,然后从该接口实现具有各自不同的行为的多个子类。接下来,程序员就可以构造命令对象,并在需要的时候使用它们:
package com; import java.util.*; import static com.AlarmPoints.*; enum AlarmPoints { STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY, KITCHEN } interface Command { void action(); } public class EnumMaps { public static void main(String[] args) { EnumMap<AlarmPoints,Command> em = new EnumMap<AlarmPoints,Command>(AlarmPoints.class); em.put(KITCHEN, new Command() { public void action() { print("Kitchen fire!"); } }); em.put(BATHROOM, new Command() { public void action() { print("Bathroom alert!"); } }); for(Map.Entry<AlarmPoints,Command> e : em.entrySet()) { printnb(e.getKey() + ": "); e.getValue().action(); } try { // If there's no value for a particular key: em.get(UTILITY).action(); } catch(Exception e) { print(e); } } public static void print(Object obj) { System.out.println(obj); } public static void printnb(Object obj) { System.out.print(obj); } } /* Output: BATHROOM: Bathroom alert! KITCHEN: Kitchen fire! java.lang.NullPointerException *///:~
2职责链设计模式
程序员以多种不同的方式来解决一个问题,然后将它们链接起来。当一个请求到来时,它遍历这个链,直到链中的某个解决方案能够处理该请求。
下面的代码中,每一次尝试可以看作一个策略。
package com;//: enumerated/PostOffice.java // Modeling a post office. import java.util.*; class Enums { private static Random rand = new Random(47); public static <T extends Enum<T>> T random(Class<T> ec) { return random(ec.getEnumConstants()); } public static <T> T random(T[] values) { return values[rand.nextInt(values.length)]; } } class Mail { // The NO's lower the probability of random selection: enum GeneralDelivery {YES,NO1,NO2,NO3,NO4,NO5} enum Scannability {UNSCANNABLE,YES1,YES2,YES3,YES4} enum Readability {ILLEGIBLE,YES1,YES2,YES3,YES4} enum Address {INCORRECT,OK1,OK2,OK3,OK4,OK5,OK6} enum ReturnAddress {MISSING,OK1,OK2,OK3,OK4,OK5} GeneralDelivery generalDelivery; Scannability scannability; Readability readability; Address address; ReturnAddress returnAddress; static long counter = 0; long id = counter++; public String toString() { return "Mail " + id; } public String details() { return toString() + ", General Delivery: " + generalDelivery + ", Address Scanability: " + scannability + ", Address Readability: " + readability + ", Address Address: " + address + ", Return address: " + returnAddress; } // Generate test Mail: public static Mail randomMail() { Mail m = new Mail(); m.generalDelivery= Enums.random(GeneralDelivery.class); m.scannability = Enums.random(Scannability.class); m.readability = Enums.random(Readability.class); m.address = Enums.random(Address.class); m.returnAddress = Enums.random(ReturnAddress.class); return m; } public static Iterable<Mail> generator(final int count) { return new Iterable<Mail>() { int n = count; public Iterator<Mail> iterator() { return new Iterator<Mail>() { public boolean hasNext() { return n-- > 0; } public Mail next() { return randomMail(); } public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; } }; } } public class PostOffice { enum MailHandler { GENERAL_DELIVERY { boolean handle(Mail m) { switch(m.generalDelivery) { case YES: print("Using general delivery for " + m); return true; default: return false; } } }, MACHINE_SCAN { boolean handle(Mail m) { switch(m.scannability) { case UNSCANNABLE: return false; default: switch(m.address) { case INCORRECT: return false; default: print("Delivering "+ m + " automatically"); return true; } } } }, VISUAL_INSPECTION { boolean handle(Mail m) { switch(m.readability) { case ILLEGIBLE: return false; default: switch(m.address) { case INCORRECT: return false; default: print("Delivering " + m + " normally"); return true; } } } }, RETURN_TO_SENDER { boolean handle(Mail m) { switch(m.returnAddress) { case MISSING: return false; default: print("Returning " + m + " to sender"); return true; } } }; abstract boolean handle(Mail m); } static void handle(Mail m) { for(MailHandler handler : MailHandler.values()) if(handler.handle(m)) return; print(m + " is a dead letter"); } public static void main(String[] args) { for(Mail mail : Mail.generator(10)) { print(mail.details()); handle(mail); print("*****"); } } public static void print(Object obj) { System.out.println(obj); } } /* Output: Mail 0, General Delivery: NO2, Address Scanability: UNSCANNABLE, Address Readability: YES3, Address Address: OK1, Return address: OK1 Delivering Mail 0 normally ***** Mail 1, General Delivery: NO5, Address Scanability: YES3, Address Readability: ILLEGIBLE, Address Address: OK5, Return address: OK1 Delivering Mail 1 automatically ***** Mail 2, General Delivery: YES, Address Scanability: YES3, Address Readability: YES1, Address Address: OK1, Return address: OK5 Using general delivery for Mail 2 ***** Mail 3, General Delivery: NO4, Address Scanability: YES3, Address Readability: YES1, Address Address: INCORRECT, Return address: OK4 Returning Mail 3 to sender ***** Mail 4, General Delivery: NO4, Address Scanability: UNSCANNABLE, Address Readability: YES1, Address Address: INCORRECT, Return address: OK2 Returning Mail 4 to sender ***** Mail 5, General Delivery: NO3, Address Scanability: YES1, Address Readability: ILLEGIBLE, Address Address: OK4, Return address: OK2 Delivering Mail 5 automatically ***** Mail 6, General Delivery: YES, Address Scanability: YES4, Address Readability: ILLEGIBLE, Address Address: OK4, Return address: OK4 Using general delivery for Mail 6 ***** Mail 7, General Delivery: YES, Address Scanability: YES3, Address Readability: YES4, Address Address: OK2, Return address: MISSING Using general delivery for Mail 7 ***** Mail 8, General Delivery: NO3, Address Scanability: YES1, Address Readability: YES3, Address Address: INCORRECT, Return address: MISSING Mail 8 is a dead letter ***** Mail 9, General Delivery: NO1, Address Scanability: UNSCANNABLE, Address Readability: YES2, Address Address: OK1, Return address: OK4 Delivering Mail 9 normally ***** *///:~
3模板方法
一些功能在基类中实现,并且其一个或多个抽象方法在派生类中定义,这种结构在设计模式中称为模板方法。
例如下面的PairManager类:
//: concurrency/CriticalSection.java // Synchronizing blocks instead of entire methods. Also // demonstrates protection of a non-thread-safe class // with a thread-safe one. package com; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.*; class Pair { // Not thread-safe private int x, y; public Pair(int x, int y) { this.x = x; this.y = y; } public Pair() { this(0, 0); } public int getX() { return x; } public int getY() { return y; } public void incrementX() { x++; } public void incrementY() { y++; } public String toString() { return "x: " + x + ", y: " + y; } public class PairValuesNotEqualException extends RuntimeException { public PairValuesNotEqualException() { super("Pair values not equal: " + Pair.this); } } // Arbitrary invariant -- both variables must be equal: public void checkState() { if(x != y) throw new PairValuesNotEqualException( 4000 ); } } // Protect a Pair inside a thread-safe class: abstract class PairManager { AtomicInteger checkCounter = new AtomicInteger(0); protected Pair p = new Pair(); private List<Pair> storage = Collections.synchronizedList(new ArrayList<Pair>()); public synchronized Pair getPair() { // Make a copy to keep the original safe: return new Pair(p.getX(), p.getY()); } // Assume this is a time consuming operation protected void store(Pair p) { storage.add(p); try { TimeUnit.MILLISECONDS.sleep(50); } catch(InterruptedException ignore) {} } public abstract void increment(); } // Synchronize the entire method: class PairManager1 extends PairManager { public synchronized void increment() { p.incrementX(); p.incrementY(); store(getPair()); } } // Use a critical section: class PairManager2 extends PairManager { public void increment() { Pair temp; synchronized(this) { p.incrementX(); p.incrementY(); temp = getPair(); } store(temp); } } class PairManipulator implements Runnable { private PairManager pm; public PairManipulator(PairManager pm) { this.pm = pm; } public void run() { while(true) pm.increment(); } public String toString() { return "Pair: " + pm.getPair() + " checkCounter = " + pm.checkCounter.get(); } } class PairChecker implements Runnable { private PairManager pm; public PairChecker(PairManager pm) { this.pm = pm; } public void run() { while(true) { pm.checkCounter.incrementAndGet(); pm.getPair().checkState(); } } } public class CriticalSection { // Test the two different approaches: static void testApproaches(PairManager pman1, PairManager pman2) { ExecutorService exec = Executors.newCachedThreadPool(); PairManipulator pm1 = new PairManipulator(pman1), pm2 = new PairManipulator(pman2); PairChecker pcheck1 = new PairChecker(pman1), pcheck2 = new PairChecker(pman2); exec.execute(pm1); exec.execute(pm2); exec.execute(pcheck1); exec.execute(pcheck2); try { TimeUnit.MILLISECONDS.sleep(500); } catch(InterruptedException e) { System.out.println("Sleep interrupted"); } System.out.println("pm1: " + pm1 + "\npm2: " + pm2); System.exit(0); } public static void main(String[] args) { PairManager pman1 = new PairManager1(), pman2 = new PairManager2(); testApproaches(pman1, pman2); } } /* Output: (Sample) pm1: Pair: x: 15, y: 15 checkCounter = 272565 pm2: Pair: x: 16, y: 16 checkCounter = 3956974 *///:~
4策略设计模式
Delayed接口有一个方法为getDelay(TimeUnit unit),这个方法强制我们去使用TimeUnit类,可以很容易地转换单位而无需作任何声明,这是策略设计模式的一个简单示例,在这种模式中,算法的一部分是作为参数传递进来的。
5代理
代理是为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。
package com;//: typeinfo/SimpleProxyDemo.java
interface Interface {
void doSomething();
void somethingElse(String arg);
}
class RealObject implements Interface {
public void doSomething() { System.out.println("doSomething"); }
public void somethingElse(String arg) {
System.out.println("somethingElse " + arg);
}
}
class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
public void doSomething() {
System.out.println("SimpleProxy doSomething");
proxied.doSomething();
}
public void somethingElse(String arg) {
System.out.println("SimpleProxy somethingElse " + arg);
proxied.somethingElse(arg);
}
}
class SimpleProxyDemo {
public static void consumer(Interface iface) {
iface.doSomething();
iface.somethingElse("bonobo");
}
public static void main(String[] args) {
consumer(new RealObject());
consumer(new SimpleProxy(new RealObject()));
}
} /* Output:
doSomething
somethingElse bonobo
SimpleProxy doSomething
doSomething
SimpleProxy somethingElse bonobo
somethingElse bonobo
*///:~
相关文章推荐
- java编程思想复用,多态,以及设计模式-多态
- java语言讲解singleton的编程思想---深入浅出单实例Singleton设计模式
- Java编程思想笔记02:组合与继承、final、策略设计模式与适配器模式、内部类、序列化控制(注意事项)
- Java I/O编程 装饰设计模式及应用
- JAVA并发设计模式学习笔记(一)—— JAVA多线程编程
- 《Java编程思想_ 深入理解java虚拟机_Thinking in java__Effiect java__设计模式》学习笔记7——泛型编程基础
- JAVA23种设计模式(另类思想)
- 征求关于java编程思想的教学材料(教学设计文档、PPT等)
- 详解。。java设计思想与设计模式------Beginer
- 设计模式Java的23种设计模式23种设计模式编程java
- java中的缓存思想与相应的设计模式
- Java设计模式编程中的工厂方法模式和抽象工厂模式
- 设计模式在Java数据库编程中的运用
- java设计模式之面向对象思想
- Java编程思想之-主板设计
- 用设计模式的思想来定制Java中的事件
- 设计模式在Java数据库编程中的运用
- java 的builder模式——设计思想
- 设计模式在Java数据库编程中的运用(二)
- java23设计模式思想