设计模式大类--结构模式(上)
大概有7中结构模式,分为上下两篇。
一、Adapter(适配器)
描述:将两个不兼容的类结合一起使用,一般需要用到其中某个类的若干方法
好处:在两个类直接创建一个混合接口,而不必修改类里面的其他代码
例子:
假设我们要打桩,有两种类:方形桩 圆形桩.
public class SquarePeg{
public void insert(String str){
System.out.println("SquarePeg insert():"+str);
}
}
public class RoundPeg{
public void insertIntohole(String msg){
System.out.println("RoundPeg insertIntoHole():"+msg);
}
}
现在有一个应用,需要既打方形桩,又打圆形桩.那么我们需要将这两个没有关系的类综合应用.假设RoundPeg我们没有源代码,或源代码我们不想修改,那么我们使用Adapter来实现这个应用:
public class PegAdapter extends SquarePeg{
private RoundPeg roundPeg;
public PegAdapter(RoundPeg peg)(this.roundPeg=peg;)
public void insert(String str){ roundPeg.insertIntoHole(str);}
}
二、Facade(外观)
描述:为子系统的一组接口提供一个一致的界面
好处:将其中不变的部分提炼出来,做成一个接口供上层使用,降低系统的复杂性,增加了灵活性
例子:
新建赛车类:
package car_package;
public class car {
public void start() {
System.out.println("车子已启动");
}
public void check_stop() {
System.out.println("刹车检查");
}
public void check_box() {
System.out.println("检查油箱");
}
public void check_console() {
System.out.println("检查仪表盘是否异常");
}
}
新建赛车操作的外观类:
package car_facade;
import car_package.car;
public class car_facade_imple {
public void car_go_go(car car_ref) {
car_ref.check_box();
car_ref.check_console();
car_ref.check_stop();
car_ref.start();
}
}
新建客户端运行类:
package run_main;
import car_facade.car_facade_imple;
import car_package.car;
public class run_main {
public static void main(String[] args) {
car_facade_imple car_facade_imple_ref = new car_facade_imple();
car_facade_imple_ref.car_go_go(new car());
}
}
三、Proxy(代理模式)
描述:为其他对象提供一种代理已控制对这个对象的访问
好处:对于开销很大,只有使用时才创建的情况下,可以使用代理
例子:
比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时是这样的体现的
先说说这个场景中的要素:一种类型的女人,潘金莲,王婆,西门庆,后来扩展的贾氏也和西门庆勾上了,我们是假设的,然后西门庆找潘金莲happy,但潘金莲不好意思直接,就找个王婆代理呗。我们看看具体代码。
先定义一种女人
public interface KindWoman {
//这种女人能做什么事情呢?
public void makeEyesWithMan();//抛媚眼
public void happyWithMan();//和男人那个....
}
一种类型嘛,那肯定是接口,定义个潘金莲
public class PanJinLian implements KindWoman{
@Override
public void happyWithMan() {
System.out.println("潘金莲和男人在做那个...");
}
@Override
public void makeEyesWithMan() {
System.out.println("潘金莲抛媚眼...");
}
}
再定义个丑陋的王婆
public class WangPo implements KindWoman {
private KindWoman kindWoman;
public WangPo(){
//默认的话是潘金莲的代理
this.kindWoman = new PanJinLian();
}
//她可以是KindWomam的任何一个女人的代理,只要你是这一类型
public WangPo(KindWoman kindWoman){
this.kindWoman = kindWoman;
}
@Override
public void happyWithMan() {
//自己老了,干不了了,但可以叫年轻的代替。
this.kindWoman.happyWithMan();
}
@Override
public void makeEyesWithMan() {
//王婆年纪大了,谁看她抛媚眼啊
this.kindWoman.makeEyesWithMan();
}
}
两个女主角都上场了,该男主角了,定义个西门庆
package com.yangguangfu.proxy;
public class XiMenQiang {
/**
* @param args
*/
public static void main(String[] args) {
WangPo wangPo;
//把王婆叫出来
wangPo = new WangPo();
//然后西门庆说,我要和潘金莲Happy,然后王婆就安排了西门庆丢筷子哪出戏:
wangPo.makeEyesWithMan();
//看到没有表面是王婆在做,其实爽的是潘金莲
wangPo.happyWithMan();
}
}
那这就是活生生的一个例子,通过代理人实现了某种目的,如果真去了王婆这个中间环节,
大郎看得紧(理解为这个对象开销很大),估计西门庆很难和潘金莲勾搭。
四、Composite(组合)
描述:将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性
好处:a、可以一致使用组合结构和单个对象;b、不必关心组合体内是否加入新部件
例子:
Component接口:
public interface Component {
public void add(Component e);
public void del(Component e);
public Component get(int i);
public void operate();
}
元素节点 Leaf:
public class Leaf implements Component {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void add(Component e) {
}
@Override
public void del(Component e) {
}
@Override
public Component get(int i) {
return null;
}
@Override
public void operate() {
System.out.println(name);
}
}
部分整体Composite:
public class Composite implements Component {
private List<Component> list = new ArrayList();
@Override
public void add(Component e) {
list.add(e);
}
@Override
public void del(Component e) {
list.remove(e);
}
@Override
public Component get(int i) {
return list.get(i);
}
@Override
public void operate() {
Iterator it = list.iterator();
while(it.hasNext()){
Component component = (Component) it.next();
component.operate();
}
}
}
客户端代码调用:
public class Customer {
public static void main(String[] args) {
Leaf leaf1 = new Leaf();
leaf1.setName("leaf1");
Leaf leaf2 = new Leaf();
leaf2.setName("leaf2");
Leaf leaf3 = new Leaf();
leaf3.setName("leaf3");
Leaf leaf4 = new Leaf();
leaf4.setName("leaf4");
Leaf leaf5 = new Leaf();
leaf5.setName("leaf5");
Composite composite1 = new Composite();
Composite composite2 = new Composite();
Composite composite3 = new Composite();
composite3.add(leaf5);
composite2.add(composite3);
composite2.add(leaf4);
composite2.add(leaf3);
composite1.add(composite2);
composite1.add(leaf2);
composite1.add(leaf1);
composite1.operate();
}
}
客户端代码可以轻松的调用组合对象的方法,不管里面的元素的个数有多少,树形组织结构如何,客户端都只用相同的代码便可,不用修改原有的代码