接口型模式
1.Adapter(适配器)模式
对象适 配器(Object Adapter)
public interface IPeg {void insertIntoHole();}public class SquarePeg implements IPeg {@Overridepublic void insertIntoHole() {System.out.println("I'm inserting into square hole...");// other logic...}}public interface IRoundPeg {void insertIntoRoundHole();}public class RoundPeg implements IRoundPeg {@Overridepublic void insertIntoRoundHole() {System.out.println("I'm inserting into round hole...");// other logic...}}public class RoundPegAdapter implements IPeg {private IRoundPeg roundPeg;public RoundPegAdapter(IRoundPeg roundPeg) {this.roundPeg = roundPeg;}@Overridepublic void insertIntoHole() {roundPeg.insertIntoRoundHole();}}类适配器

public class RoundPegAdapter2 extends RoundPeg implements IPeg {@Overridepublic void insertIntoHole() {super.insertIntoRoundHole();}}双向适配器

public class TwoWayPegAdapter implements IRoundPeg, IPeg {private IPeg squarePeg;private IRoundPeg roundPeg;public TwoWayPegAdapter(IPeg squarePeg) {this.squarePeg = squarePeg;}public TwoWayPegAdapter(IRoundPeg roundPeg) {this.roundPeg = roundPeg;}@Overridepublic void insertIntoRoundHole() {squarePeg.insertIntoHole();}@Overridepublic void insertIntoHole() {roundPeg.insertIntoRoundHole();}}测试
public class TestDrive {public static void main(String[] args) {TestDrive test = new TestDrive();IPeg squarePeg = new SquarePeg();IRoundPeg roundPeg = new RoundPeg();RoundPegAdapter adpater = new RoundPegAdapter(roundPeg);System.out.println("Testing square peg...");test.testPeg(squarePeg);System.out.println("\nTesting square adapter peg...");test.testPeg(adpater);TwoWayPegAdapter roundPeg2 = new TwoWayPegAdapter(roundPeg);TwoWayPegAdapter squarePeg2 = new TwoWayPegAdapter(squarePeg);System.out.println("\nTesting a 2-way square adapter peg...");test.testPeg(roundPeg2);System.out.println("\nTesting 2-way round adapter peg...");test.testRoundPeg(squarePeg2);}private void testPeg(IPeg peg) {peg.insertIntoHole();}private void testRoundPeg(IRoundPeg peg) {peg.insertIntoRoundHole();}}2.Facade(外观)模式
目的:提供一个接口,使子系统更加容易使用。
通常,我们应该把子系统中的类重构为一个个目的明确的类。这样做可以使代码更加容易维护,但是这样也会让子系统用户不知从何处开始。为了便于子系统用户的使用,我们可以在子系统中顺带提供一些示例类或者外观类。示例类通常是指能够独立运行但不可复用的应用程序,仅用来示范子系统的用法。外观类通常是一个可配置、可复用的类,它为方便用户使用子系统提供了一个更高层次的接口。
总结:外观封装了子系统之间复杂的交互和依赖关系,为客户对象提供了单一简单的界面,降低了系统的复杂性。在讲解外观模式同时,介绍了 最少知识原则,我们知道,类之间耦合度越低,越易扩展和实现重用。
public class HotelReceptionist { public void subscribe() { System.out.println("Subscribe a table..."); }}public class Cook { public void cookDish() { System.out.println("Cooking dishes..."); }}public class Waitress { public void serveDishes() { System.out.println("Serving dishes..."); } public void waitForAnOrder() { System.out.println("Waiting for the order..."); }}public class Cashier { public void check() { System.out.println("Check the bill..."); }}public class Assistant { private HotelReceptionist hotelReceptionist; private Cook cook; private Waitress waitress; private Cashier cashier; public Assistant(HotelReceptionist hotelReceptionist, Cook cook, Waitress waitress, Cashier cashier) { this.hotelReceptionist = hotelReceptionist; this.cook = cook; this.waitress = waitress; this.cashier = cashier; } public void prepareDinner() { hotelReceptionist.subscribe(); waitress.waitForAnOrder(); cook.cookDish(); } public void endDinner() { waitress.serveDishes(); cashier.check(); }}public class Boss { private Assistant assistant; public Boss(Assistant assistant) { this.assistant = assistant; } public void treat() { assistant.prepareDinner(); address(); assistant.endDinner(); } private void address() { System.out.println("Boss is bitching : \"Tomorrow is going to be better, we will make blah blah...\""); }}public class FacadeTestDrive { public static void main(String[] args) { Cashier cashier = new Cashier(); Cook cook = new Cook(); HotelReceptionist hotelReceptionist = new HotelReceptionist(); Waitress waitress = new Waitress(); Assistant assistant = new Assistant(hotelReceptionist, cook, waitress, cashier); Boss boss = new Boss(assistant); boss.treat(); }}3.Composite(组合)模式
目的:让用户能够用统一的接口处理单个对象以及对象组合。
常见的组合
Composite模式包含两个相关的重要概念。其中一个概念是群组可以包含个体对象,也可以包含其他的群组。与此相关的另一个概念是群组和个体对象可以共享同一个接口。将这些概念应用于对象建模,就可以创建一个抽象类或Java接口来定义群组对象和个体对象的公有特性。
组合对象模式中的方法通常采用递归定义。由于递归的存在,在编写代码的时候需要谨防死循环。不过,只要通过采取措施保证组合对象模型为树状结构,就可一避免这类问题。另外,组合对象模型中也可以出现环,但是我们必须修改算法来监控可能出现的无穷尽递归。
安全的组合模式

public abstract class BranchComponent { public String getName() { throw new UnsupportedOperationException(); } public String getDiscription() { throw new UnsupportedOperationException(); } public void display() { throw new UnsupportedOperationException(); }}import java.util.ArrayList;import java.util.List;public class BranchComposite extends BranchComponent { private String name; private String discription; private List<BranchComponent> childrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList<BranchComponent>(); } public void display() { System.out.printf("%s: %s\n", name, discription); for (BranchComponent child : childrenBranch) { child.display(); } } public String getName() { return name; } public String getDiscription() { return discription; } public void add(BranchComponent child) { childrenBranch.add(child); } public void remove(BranchComponent child) { childrenBranch.remove(child); } public BranchComponent getChild(int index) { return childrenBranch.get(index); }}public class BranchLeaf extends BranchComponent { private String name; private String discription; public BranchLeaf(String name, String discription) { this.name = name; this.discription = discription; } public void display() { System.out.printf("\t%s: %s\n", name, discription); } public String getName() { return name; } public String getDiscription() { return discription; }}public class TestDrive { public static void main(String[] args) { BranchComposite china = new BranchComposite("CN", "China Branch"); BranchComposite shanghai = new BranchComposite("Sh", "Shanghai Branch"); BranchLeaf huangpu = new BranchLeaf("Hp", "Huangpu Branch"); BranchLeaf yangpu = new BranchLeaf("Yp", "Yangpu Branch"); BranchLeaf pudong = new BranchLeaf("Pd", "Pudong Branch"); BranchComposite beijing = new BranchComposite("Bj", "Beijing Branch"); BranchLeaf dongcheng = new BranchLeaf("Dc", "Dongcheng Branch"); BranchLeaf xicheng = new BranchLeaf("Xc", "Xicheng Branch"); BranchLeaf haidian = new BranchLeaf("Hd", "Haidian Branch"); shanghai.add(huangpu); shanghai.add(yangpu); shanghai.add(pudong); beijing.add(dongcheng); beijing.add(xicheng); beijing.add(haidian); china.add(shanghai); china.add(beijing); System.out.println("Displaying the head bank information"); display(china); System.out.println("\nDisplaying Shanghai bank branch information"); display(shanghai); System.out.println("\nDisplaying Pudong bank branch information in Shanghai"); display(pudong); } private static void display(BranchComponent branch) { branch.display(); }}透明的组合模式

public abstract class BranchComponent { public String getName() { throw new UnsupportedOperationException(); } public String getDiscription() { throw new UnsupportedOperationException(); } public void display() { throw new UnsupportedOperationException(); } public void add(BranchComponent child) { throw new UnsupportedOperationException(); } public void remove(BranchComponent child) { throw new UnsupportedOperationException(); } public BranchComponent getChild(int index) { throw new UnsupportedOperationException(); }}import java.util.ArrayList;import java.util.List;public class BranchComposite extends BranchComponent { private String name; private String discription; private List<BranchComponent> childrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList<BranchComponent>(); } public void display() { System.out.printf("%s: %s\n", name, discription); for (BranchComponent child : childrenBranch) { child.display(); } } public String getName() { return name; } public String getDiscription() { return discription; } public void add(BranchComponent child) { childrenBranch.add(child); } public void remove(BranchComponent child) { childrenBranch.remove(child); } public BranchComponent getChild(int index) { return childrenBranch.get(index); }}public class BranchLeaf extends BranchComponent { private String name; private String discription; public BranchLeaf(String name, String discription) { this.name = name; this.discription = discription; } public void display() { System.out.printf("\t%s: %s\n", name, discription); } public String getName() { return name; } public String getDiscription() { return discription; }}public class TestDrive { public static void main(String[] args) { BranchComposite china = new BranchComposite("CN", "China Branch"); BranchComposite shanghai = new BranchComposite("Sh", "Shanghai Branch"); BranchLeaf huangpu = new BranchLeaf("Hp", "Huangpu Branch"); BranchLeaf yangpu = new BranchLeaf("Yp", "Yangpu Branch"); BranchLeaf pudong = new BranchLeaf("Pd", "Pudong Branch"); BranchComposite beijing = new BranchComposite("Bj", "Beijing Branch"); BranchLeaf dongcheng = new BranchLeaf("Dc", "Dongcheng Branch"); BranchLeaf xicheng = new BranchLeaf("Xc", "Xicheng Branch"); BranchLeaf haidian = new BranchLeaf("Hd", "Haidian Branch"); shanghai.add(huangpu); shanghai.add(yangpu); shanghai.add(pudong); beijing.add(dongcheng); beijing.add(xicheng); beijing.add(haidian); china.add(shanghai); china.add(beijing); System.out.println("Displaying the head bank information"); display(china); System.out.println("\nDisplaying Shanghai bank branch information"); display(shanghai); System.out.println("\nDisplaying Pudong bank branch information in Shanghai"); display(pudong); } private static void display(BranchComponent branch) { branch.display(); }}4.Bridge(桥接)模式
意图:将抽象与抽象方法的实现相分离,这样他们就可以独立变化。
抽象就是指依赖于一系列抽象方法的类。最简单的抽象实例是抽象的类层次结构,其中超类中的具体类依赖于其他抽象类。如果希望用另一种机器的排列方式来构造最初的类层次结构,就必须把那些抽象的方法移到另一种类层次结构中。在这种情况下,我们可以使用Bridge模式,将抽象与其抽象方法的实现相分离。
Bridge模式是常见的例子就是驱动程序,比如数据库驱动程序。数据库驱动程序提供了Bridge模式结构中固有的权衡的良好实例。一个驱动程序可能会请求某个实现程序不支持的方法。另一方面,驱动程序可能会忽略应用到某个特定数据库的有用方法。这将迫使我们重新编写针对实现而不是抽象的代码。我们是否应该更重视抽象而不是具体并非一直都很明朗,但是有意地做这些决定是非常重要的.