关注公众号获取更多资料
html
@java
结构型模式描述如何将类或者对象按照某种布局组成更大的结构。组合关系或者聚合关系的耦合度比继承低,知足“合成复用原则”。结构型模式主要有如下几种:设计模式
代理模式在框架中很常见,Spring AOP就是经过代理模式实现的 。安全
代理模式主要有如下几个角色:app
代理模式的类结构以下:框架
举例说明:ide
interface ProxyInterface { void say(); }
class RealObject implements ProxyInterface { @Override public void say() { System.out.println("hello"); } }
class ProxyObject implements ProxyInterface { RealObject obj; @Override public void say() { if (obj == null) obj = new RealObject(); preSay(); obj.say(); afterSay(); } private void preSay() { System.out.println("proxy in..."); } private void afterSay() { System.out.println("proxy out..."); } }
public class ProxyDemo { public static void main(String[] args) { ProxyObject proxy = new ProxyObject(); proxy.say(); } } //输出 //proxy in... //hello //proxy out...
在代理类中使用了真实主题对象,并在调用方法先后执行代理方法。代理类主要做用是隐藏了真实主题,在必定程度上起到了保护做用。oop
适配器模式是将一个类的接口转换为用户但愿的另外一个接口,解决了由于接口不兼容而不能一块儿工做的问题。通常状况下能够分为类适配器和对象适配器两种。布局
适配器主要包含如下几个结构:测试
类适配器经过继承和实现接口的方式完成适配过程,类图以下:
举例说明:
interface Adapter { void request(); }
class Adaptee { public void say() { System.out.println("hello from adapdee"); } }
class ClassAdapter extends Adaptee implements Adapter { @Override public void request() { say(); } }
Adapter classAdapter = new ClassAdapter(); classAdapter.request();//hello from adapdee
对象适配器,只实现了目标接口,而后在适配器中依赖适配者,使用适配者调用原有方法实现适配的方式,类结构以下:
双向适配器能够将适配者转换为目标,也能够将目标转换为适配者。他的适配器类采用对象适配器实现,以下:
class TwoWayAdapter implements Adapter, IAdaptee { private Adaptee adaptee; private Adapter adapter; public TwoWayAdapter(Adaptee adaptee) { this.adaptee = adaptee; } public TwoWayAdapter(Adapter adapter) { this.adapter = adapter; } @Override public void request() { System.out.println("适配器调用适配者..."); adaptee.say(); } @Override public void say() { System.out.println("适配者调用适配器"); adapter.request(); } }
测试:
System.out.println("--------"); TwoWayAdapter twoWayAdapter = new TwoWayAdapter(new ObjectAdapter(new Adaptee())); twoWayAdapter.say();//hello from adapdee System.out.println("--------"); TwoWayAdapter twoWayAdapter1 = new TwoWayAdapter(new Adaptee()); twoWayAdapter1.request();//hello from adapdee
现实生活中不少对象都是由多种元素组成,这些元素又会有多种变化,若是采用继承的方式将会产生不少种不一样的类,使系统臃肿冗余。好比一个产品有两种元素组成,这两种元素分别有m种和n种种类,那么若是使用继承方式,将会有m*n种可能性。
桥接模式将抽象和实现分离,使他们能够独立变化,使用组合关系替代继承,下降了多可变的状况。
桥接模式主要包含如下几个结构:
桥接模式的类图:
举例说明:女式背包有不少种种类,好比手提包,钱包等等,也有不少种颜色,使用桥接模式能够很方便的对这些属性进行组合。
abstract class Bag { public Color color; public Bag(Color color) { this.color = color; } abstract String getName(); public void say() { System.out.println("i am " + getName() + ";my color is " + color.getColor()); } }
class HandBag extends Bag { @Override String getName() { return "handBag"; } public HandBag(Color color) { super(color); } } class Wallet extends Bag { @Override String getName() { return "wallet"; } public Wallet(Color color) { super(color); } }
interface Color { String getColor(); }
class Red implements Color { @Override public String getColor() { return "red"; } } class Yellow implements Color { @Override public String getColor() { return "yellow"; } }
Bag handBag = new HandBag(new Red()); handBag.say(); Bag wallet = new Wallet(new Yellow()); wallet.say(); //i am handBag;my color is red //i am wallet;my color is yellow
装饰者模式是指在不改变现有对象结构的状况下,动态的对其增长一些职责的模式。
装饰者模式有如下几个成员:
装饰者模式的类图:
装饰者模式与代理模式都是在不改变原有类结构的基础上新增一些职责,二者功能一致,从类图上看,结构也很类似。
装饰者模式关注于在一个对象上动态的添加方法,然而代理模式关注于控制对对象的访问。换句话 说,用代理模式,代理类能够对它的客户隐藏一个对象的具体信息。所以,当使用代理模式的时候,咱们经常在一个代理类中建立一个对象的实例。而且,当咱们使用装饰器模 式的时候,咱们一般的作法是将原始对象做为一个参数传给装饰者的构造器。
能够用另一句话来总结这些差异:使用代理模式,代理和真实对象之间的的关系一般在编译时就已经肯定了,而装饰者可以在运行时递归地被构造。http://www.cnblogs.com/jaredlam/archive/2011/11/08/2241089.html)
举例说明:汽车的生产—汽车对象Car,在出厂的时候能够添加修饰,使之成为不一样类型的车辆。
interface Car { void create(); }
class MyCar implements Car { @Override public void create() { System.out.print("it's a car."); } }
abstract class DecoratorCar implements Car { private Car car; public DecoratorCar(Car car) { this.car = car; } @Override public void create() { car.create(); } abstract void change(); }
class Truck extends DecoratorCar { public Truck(Car car) { super(car); } public void create() { super.create(); change(); } @Override protected void change() { System.out.println("it's a truck."); } } class Bus extends DecoratorCar { public Bus(Car car) { super(car); } @Override public void create() { super.create(); change(); } @Override void change() { System.out.println("it's a bus."); } }
Car truck = new Truck(new MyCar()); truck.create(); //it's a car.it's a truck. Car bus = new Bus(new MyCar()); bus.create(); //it's a car.it's a truck.
装饰模式在Java中最著名的应用就是I/O库的设计了,例如InputStream的子类FileInputStream,OutputStream的子类FileOutputStream等,他们都是装饰类。
外观模式是一种经过为多个复杂的子系统提供一个一致的接口,使这些子系统更容易被访问。
外观模式一般有如下几种角色:
外观模式类图以下:
举例说明:京东购买流程包含下单,付款,打包等子系统支持
class User { private JDShopping jd = new JDShopping(); public void buy() { jd.shooping(); } }
class JDShopping { private ChooseSystem chooseSystem = new ChooseSystem(); private PaySystem paySystem = new PaySystem(); private PackageSystem packageSystem = new PackageSystem(); public void shooping() { chooseSystem.choose(); paySystem.pay(); packageSystem.packageGoods(); } }
class ChooseSystem { public void choose() { System.out.println("下单中..."); } } class PaySystem { public void pay() { System.out.println("付款中..."); } } class PackageSystem { public void packageGoods() { System.out.println("打包中..."); } }
public static void main(String[] args) { new User().buy(); //下单中... //付款中... //打包中... }
若是须要引入其余子系统,可使用以下结构:
享元模式运用了共享技术最大限度的支持大量细粒度对象的复用。享元模式主要有如下几个角色:
享元模式的类图以下:
举例说明:以围棋为例,黑白棋子除颜色之外都具有相同的属性,非享元角色为颜色,剩余为享元角色。
class PiecesColor { private String color; public PiecesColor(String color) { this.color = color; } public String getColor() { return color; } @Override public int hashCode() { return this.color.hashCode(); } @Override public boolean equals(Object color) { return this.color.equals(((PiecesColor) color).getColor()); } }
abstract class Pieces { protected String shareName = "share"; protected PiecesColor color; public Pieces(PiecesColor color) { this.color = color; } public String getShareName() { return shareName; } public PiecesColor getColor() { return color; } public void show() { System.out.println(this + "--shareName:" + shareName + "--color:" + color.getColor()); } }
class WhitePieces extends Pieces { public WhitePieces(PiecesColor color) { super(color); } } class BlackPieces extends Pieces { public BlackPieces(PiecesColor color) { super(color); } }
class PiecesFactory { //能够用任何形式储存 Map<PiecesColor, Pieces> pieces = new HashMap<>(2); public Pieces get(PiecesColor color) { if (!pieces.containsKey(color)) { System.out.println("creating..."); pieces.put(color, color.getColor().equals("white") ? new WhitePieces(color) : new BlackPieces(color)); } return pieces.get(color); } }
PiecesFactory factory = new PiecesFactory(); Pieces pieces = factory.get(new PiecesColor("white")); pieces.show(); pieces = factory.get(new PiecesColor("black")); pieces.show(); //是否再也不建立享元角色,使用现有对象 pieces = factory.get(new PiecesColor("white")); pieces.show(); pieces = factory.get(new PiecesColor("black")); pieces.show();
creating... com.wupengchoy.mystudy.designpattern.structure.WhitePieces@255316f2--shareName:share--color:white creating... com.wupengchoy.mystudy.designpattern.structure.BlackPieces@41906a77--shareName:share--color:black com.wupengchoy.mystudy.designpattern.structure.WhitePieces@255316f2--shareName:share--color:white com.wupengchoy.mystudy.designpattern.structure.BlackPieces@41906a77--shareName:share--color:black
以上结果能够看出第二次获取对象的时候享元角色并无从新建立,而是使用以前建立的对象。
组合模式又叫部分-总体模式,将对象组合成树状的层次结构的模式,表示部分和总体的关系。一般有如下几个角色:
组合模式的实现方式可分为透明式和安全式,类图和区别以下:
举例说明:超市购物袋子为例,大袋子里有小袋子,还有其余商品,小袋子里还有其余商品。
abstract class BagAndGoods { abstract void show(); }
class Milk extends BagAndGoods { public void show() { System.out.println("i am milk."); } } class Apple extends BagAndGoods { public void show() { System.out.println("i am apple."); } }
class Bags extends BagAndGoods { private List<BagAndGoods> goods = new ArrayList<>(); public void add(BagAndGoods good) { goods.add(good); } @Override public void show() { for (BagAndGoods good : goods) { good.show(); } } }
Bags bigBag = new Bags(); bigBag.add(new Milk()); Bags milddleBag = new Bags(); milddleBag.add(new Apple()); milddleBag.add(new Apple()); bigBag.add(milddleBag); //展现袋子中购买的物品 bigBag.show(); //i am milk. //i am apple. //i am apple.
若是有多个树枝和树叶,还能够对树枝和树叶再进行抽象,组成以下格式: