结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
适配器 Adapter
适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。
public class Adaptee {
public void request() {
System.out.println("连接。。。");
System.out.println("end。。。");
}
}
public class Computer {
public void net(NetUsb nt){
System.out.println("开机");
nt.handleRequest();
}
}
public interface NetUsb {
public void handleRequest();
}
//适配器
public class Adapter implements NetUsb{
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void handleRequest() {
adaptee.request();
}
}
public static void main(String[] args) {
Computer computer = new Computer();
Adaptee adaptee = new Adaptee();
Adapter adapter = new Adapter(adaptee);
computer.net(adapter);
}
装饰者 Decorator
动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。
//抽象构件
public abstract class Snack {
public String des;//描述
private float price = 0.0f; //单价
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
//计算费用 方法
public abstract float costs();
}
//手抓饼 基础构件
public class ShreddedCake extends Snack{
public ShreddedCake(){
setPrice(5.0f);
setDes("ShreddedCake :" + costs());
}
@Override
public float costs() {
return super.getPrice();
}
}
//烤冷面 基础构件
public class GrilledColdNoodles extends Snack{
public GrilledColdNoodles(){
setPrice(5.0f);
setDes("GrilledColdNoodles : " + costs() );
}
@Override
public float costs() {
return super.getPrice();
}
}
//装饰
public class Decorator extends Snack{
private Snack s;
public Decorator(Snack s) {
this.s = s;
}
@Override
public float costs() {
return super.getPrice()+s.costs();
}
@Override
public String getDes() {
//输出装饰者的信息
return des + " " + getPrice() + "+" + s.getDes();
}
}
//具体装饰角色
public class ChineseLeaf extends Decorator{
public ChineseLeaf(Snack s) {
super(s);
setDes("Chinese leaf ");
setPrice(1.0f);
}
}
public class Sausage extends Decorator{
public Sausage(Snack s) {
super(s);
setDes(" sausage");
setPrice(1.5f);
}
}
public class Egg extends Decorator{
public Egg(Snack s) {
super(s);
setDes("Egg");
setPrice(1.0f);
}
}
//测试
public static void main(String[] args) {
Snack s1 = new GrilledColdNoodles();//烤冷面
System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
s1 = new Egg(s1);//加一个鸡蛋
System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
s1 = new ChineseLeaf(s1);//加肠
System.out.println(s1.costs()+ "\t" +"constitute(组成):" +s1.getDes());
System.out.println("==================================");
Snack s2 = new ShreddedCake();//手抓饼
System.out.println(s2.costs()+ "\t" +"constitute(组成):" +s2.getDes());
}
代理Proxy
中介隔离作用:在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
//静态代理
//创建服务接口
public interface BuyHouse {
void buyHouse();
}
//实现接口
public class BuyHouseImpl implements BuyHouse{
@Override
public void buyHouse() {
System.out.println("具体实现。。。。");
}
}
//创建代理类
public class BuyHouseProxy implements BuyHouse{
private BuyHouse bh;
public BuyHouseProxy(BuyHouse bh) {
this.bh = bh;
}
@Override
public void buyHouse() {
System.out.println("begin。。。。。");
bh.buyHouse();
System.out.println("end。。。。。");
}
}
//静态代理
public class Main {
public static void main(String[] args) {
BuyHouseImpl b = new BuyHouseImpl();
b.buyHouse();
//生成代理对象
BuyHouseProxy bhp = new BuyHouseProxy(b);
bhp.buyHouse();
}
}
//动态 代理 invoke
public class ProxyHandler implements InvocationHandler {
private Object object;
public ProxyHandler(Object object) {
this.object = object;
}
@Override // 被代理对象 方法 参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
befor();
System.out.println(method.getName());
Object o = method.invoke(object, args);
after();
return o;
}
public void befor() {
System.out.println("begin........");
}
public void after() {
System.out.println("end..........");
}
}
//动态代理
public class Main {
public static void main(String[] args) {
BuyHouse bh = new BuyHouseImpl();
BuyHouse proxy = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader()
, new Class[]{BuyHouse.class}
, new ProxyHandler(bh));
proxy.buyHouse();
}
}
//cglib
public class CglibProxy {
private Object target;
public Object getInstance(final Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
befor();
Object result = methodProxy.invoke(object, args);
after();
return result;
}
public void befor(){
System.out.println("begin.......");
}
public void after(){
System.out.println("end.......");
}
}
public static void main(String[] args) {
BuyHouse buyHouse = new BuyHouseImpl();
CglibProxy cp = new CglibProxy();
BuyHouseImpl bcp = (BuyHouseImpl) cp.getInstance(buyHouse);
bcp.buyHouse();
}
外观模式 Facade
定义: 隐藏了系统的复杂性,并向客户端提供了一个可以访问系统的接口。
该模式就是把一些复杂的流程封装成一个接口供给外部用户更简单的使用。
//子系统A
public class SubSystemA {
public void start(){
System.out.println("SubSystemA.method.1...");
}
public void shotdown(){
System.out.println("SubSystemA.method.2..");
}
}
//子系统B
public class SubSystemB {
public void start(){
System.out.println("SubSystemB.method.1...");
}
public void shotdown(){
System.out.println("SubSystemB.method.2...");
}
}
==================================
//门面 外观
public class Facade {
SubSystemA ssa;
SubSystemB ssb;
public Facade() {
ssa = new SubSystemA();
ssb = new SubSystemB();
}
public void start(){
System.out.println("begin.start.");
this.ssa.start();
this.ssb.start();
System.out.println("end.start.");
}
public void down(){
System.out.println("begin.down.");
this.ssa.shotdown();
this.ssb.shotdown();
System.out.println("end.down.");
}
}
=========================
public static void main(String[] args) {
Facade facade = new Facade();
facade.start();
facade.down();
}
桥接模式 Bridge
将抽象部分与它的实现部分分离,使他们都可以独立地变化。聚合代替继承
//品牌
public interface Brand {
void info();
}
public class Apple implements Brand {
@Override
public void info() {
System.out.print("Apple");
}
}
public class Lenovo implements Brand {
@Override
public void info() {
System.out.print("Lenovo");
}
}
//抽象电脑类型
public abstract class Computer {
protected Brand brand;
public Computer(Brand brand) {
this.brand = brand;
}
public void info() {
brand.info();
}
}
class DeskType extends Computer{
public DeskType(Brand brand) {
super(brand);
}
@Override
public void info() {
brand.info();
System.out.print("\t" + "DeskType");
}
}
class Laptop extends Computer{
public Laptop(Brand brand) {
super(brand);
}
@Override
public void info() {
brand.info();
System.out.print("\t" + "Laptop");
}
}
public static void main(String[] args) {
Computer c = new DeskType(new Apple());
c.info();
System.out.println();
Computer c2 = new Laptop(new Lenovo());
c2.info();
}
组合模式Compostie
将对象组合成树形结构以表示“部分-整体”的层次结构。
abstract class Node {
abstract public void p();
}
class LeafNode extends Node {
String content;
public LeafNode(String content) {this.content = content;}
@Override
public void p() {
System.out.println(content);
}
}
class BranchNode extends Node {
List<Node> nodes = new ArrayList<>();
String name;
public BranchNode(String name) {this.name = name;}
@Override
public void p() {
System.out.println(name);
}
public void add(Node n) {
nodes.add(n);
}
}
public class Main {
public static void main(String[] args) {
BranchNode root = new BranchNode("root");
BranchNode chapter1 = new BranchNode("chapter1");
BranchNode chapter2 = new BranchNode("chapter2");
Node c1 = new LeafNode("c1");
Node c2 = new LeafNode("c2");
BranchNode b21 = new BranchNode("section2.1");
Node c21 = new LeafNode("c21");
Node c22 = new LeafNode("c22");
root.add(chapter1);
root.add(chapter2);
chapter1.add(c1);
chapter1.add(c2);
chapter2.add(b21);
b21.add(c21);
b21.add(c22);
tree(root, 0);
}
static void tree(Node b, int depth) {
for(int i=0; i<depth; i++) System.out.print("->");
b.p();
if(b instanceof BranchNode) {
for (Node n : ((BranchNode)b).nodes) {
tree(n, depth + 1);
}
}
}
享元Flyweight
在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
//抽象享元
public interface Flyweight {
// 显示票价 参数为列车类型
public void showPrice(String type);
}
//具体享元类
public class ConcreteFlyweight implements Flyweight {
String from;
String to;
public ConcreteFlyweight(String from, String to) {
this.from = from;
this.to = to;
}
@Override
public void showPrice(String type) {
if (type.equals("Gaotie")){
System.out.println("从" + from + "到" + to + "的高铁票价为198");
}else{
System.out.println("从" + from + "到" + to + "的高铁票价为98");
}
}
}
//享元工厂类
public class FlyweightFactory {
static Map<String, Flyweight> map = new HashMap<String, Flyweight>();
public static Flyweight getFlyweight(String from, String to) {
String k = from + to;
if (map.containsKey(k)) {
System.out.println("使用存在 containsKey 查询" + k);
return map.get(k);
}else {
System.out.println("创建对象 查询 " + k);
ConcreteFlyweight concreteFlyweight = new ConcreteFlyweight(from, to);
map.put(k,concreteFlyweight);
return concreteFlyweight;
}
}
}
=======
public static void main(String[] args) {
FlyweightFactory.getFlyweight("北京","上海").showPrice("Gaotie");
FlyweightFactory.getFlyweight("北京","上海").showPrice("Dongche");
}