结构型设计模式学习

来源:互联网 发布:域名缩短器 编辑:程序博客网 时间:2024/06/16 12:50
//1.Composite 组合模式
//意图:将对象组合成树形结构以表示部分-整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性

//类图:组合模式的类图十分类似于数据结构的树形结构:


//component
public abstract class Component{
public abstrsct void draw();
public void add(Component comp){
}
public Component getComponent(int n){
return null;
}
}
//leaf1
public class Leaf1 extends Component{
public void draw(){
System.out.println("draw a leaf1");
}
}
//leaf2
public class Leaf2 extends Component{
public void draw(){
System.out.println("draw a leaf2");
}
}
//Composite
public class Composite extends Component{
private List<Component> compList;


public Composite(){
compList=new ArrayList<Component>();
}


public void draw(){
for(int i=0;i<compList.size();i++){
compList.get(i).draw();
}
}
}
//test
public class Test{
public static void main(String[] args){
Component cpn=new Composite();
cpn.add(new Leaf1());
cpn.add(new Leaf2());


Composite c=new Composite();
c.add(new Leaf2);


cpn.add(c);


cpn.draw();       //out : leaf1 ,leaf2 ,leaf2
}
}
//适用:
//想表示对象的部分-整体层次
//希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象
//往往和Iterator、Visitor、Flyweight、Decorator等模式一起使用,主要用在GUI设计等方面


//2.Facade 外观模式
//意图:为子系统的一组接口提供一个一致的界面。

//此模式简单实用,主要功能就是封装,解耦。


//适用:
//当你要为一个复杂的子系统提供一个简单接口时
//客户程序与抽象类的实现部分之间存在很大的依赖性
//当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点


//3.Proxy 代理模式
//意图:为其他对象提供一种代理以控制对这个对象的访问

//这里有三个类,IObject是一个抽象类,作为接口使用,IObjectImpl是业务相关类,即执行具体操作的实现类,IOjbectProxy是代理类,Client通过这个类来间接访问IObjectImpl。这里写一
//下最简单的代理模式:
public interface IObject{
public void operation();
}


public class IObjectImpl implements IObject{
public void operation(){
System.out.println("operate by objectimpl");
}
}


public class IObjectProxy implements IObject{
private IObject object;
public IObjectProxy(){
object=new IObjectImpl();
}
public void operation(){
System.out.println(" before operation");
object.operation();
System.out.println(" after operation");
}
}
//test
public class Test{
public static vois main(String[] args){
IObject objectProxy=new IObjectProxy();
objectProxy.operation();
}
}


//代理模式可分为远程代理,虚代理,保护代理,智能引用等情况,分别适用于不同场景


//4.Adapter适配器模式
//意图:将一类的接口转换为用户希望的另一类接口。Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。

//角色:目标接口(Target):客户所期待的接口。是指客户能用的接口,适配器就是将客户不能直接使用的接口是配成这一接口。
//需要适配的接口(类)(Adaptee):因接口不兼容而被适配的接口。
//适配器(Adapter):将Adaptee是配成Target的类。
public class Target{
public void doSomething(){
System.out.println("aaaaaaa");
}
}


public class Adaptee{
public void doMyThing(){
System.out.println("bbbbbbb");
}
}


public class Adapter extends Target{
private Adaptee adaptee;
public Adapter(){
adaptee=new Adaptee();
}
public void doSomething(){
adaptee.doMyThing();
}
}
//test
public class Test{
public static void main(String args[]){
Target t=new Adapter();
t.doSomething();      //输出bbbbbb
}
}
//通过上面的例子我们可以看到,客户可以通过使用Target的doSomething方式来使用Adaptee的doMything方法;
//适用:
//系统需要使用现有的类,而这些类的接口不符合系统的接口。
//使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。


//5.Decrator装饰模式

//意图:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。 


//Component 定义了一个接口,可以利用Decorator动态地给他增加职责

//ConcreteComponent定义了一个实现了Component接口的对象
//Decorator是抽象装饰者类,继承自Component接口,并包含有一个实现了Component接口的对象
//ConcreteDecorator是具体装饰者类,用于为ConcreteComponent增加职责
//在以上结构中,Component和Decorator可以情况省略。
public class Car{
public void description(){
System.out.println("Basic Car");
}
}
//太阳顶的车装饰
public class SunRoofDecorator extends Car{
private Car car;
public SunRoofDecorator(Car car){
this.car=car;
}
public void description(){
car.Description();
System.out.println("Add  sunroof");
}
}
//test
public class Test{
public void static main(String[] args){
Car car=new SunRoofDecorator(new Car());
car.description();
}
}


//5.Bridge桥接模式

//意图:将抽象部分与它的实现部分相分离,使他们可以独立的变化。


//例,假如我们的面包分为黑色和白色面包,已经通过继承实现,现在要添加三角形和方形面包,可以通过桥接模式实现
//ps:如果在开始设计,可以使用抽象工厂模式,但是现在的前提是颜色分类已经实现。
public class BreadImpl{
public String shape(){


}
}


public class Bread{
private BreadImpl impl;
public void setImpl(BreadImpl impl){
this.impl=impl;
}
public String look(){
return impl.shape();
}
}
//从代码中可以看出Bread有添加一个BreadImpl类型的成员变量,并且有一个setImpl方法可以在运行时动态修改实现,这就是所谓的桥,也就是桥接模式的核心。BreadImpl有一个shape方法返回形状,而Bread类中有一个look方法返回面包的外观。
//颜色实现
public class WhiteBread extends Bread{
public String look(){
return super.look()+" white";
}
}


public class BlackBread extends Bread{
public String look(){
return super.look()+" black";
}
}
//形状实现
public class TriBread extends BreadImpl{
public String shape(){
return "triangle";
}
}


public class RectBread extends BreadImpl{
public String shape(){
return "rectangle";
}
}
//test
public class Test{
public void static main(String[] args){
Bread bread=new BlackBread();
bread.setImpl(new TriBread());
System.out.println(bread.look());  //out : "triangle  black"
}
}


// 适用:
//不希望在抽象和它的实现部分之间有一个固定的绑定关系,希望在程序运行时刻实现部分应可以被选择或者切换
//类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充




//6.FlyWeight 享元模式

//意图:利用共享以支持大量细粒度对象的技术。


//FlyweightFactory是产生Flyweight的一个工厂,client可以通过getFlyweight方法取得,它有一个参数key,因此其中中必然存在类似于Map之类的数据结构存储Flyweight对象。
//Flyweight类是一个抽象类,它有两个子类ConcreteFlyweight和UnsharedConcreteFlyweight,分别对应共享的享元对象和不共享的享元对象。因为不是所有的Flyweight子类都必须是共享的,UnsharedConcreteFlyweight类使得共享变得更灵活。
//代码只考虑共享部分
public abstrsct class FlyWeight{
public abstrsct void set(String str);
public abstrsct void operation();
}


public ConcreteFlyWeight extends FlyWeight{
private String something;
public ConcreteFlyWeight(String str){
this.something=str;
}
public void set(String str){
this.something=str;
}
public void operation(){
System.out.println(something);
}
}


public class FlyWeightFactory{
private Map<String,FlyWeight> list;
public FlyWeight getFlyWeight(String key){
FlyWeight f=list.get(key);
if(f==null){
f=new ConcreteFlyWeight(key);
list.put(key,f)
}
return f;
}
}


//test
public class Test{
public void static main(String[] args){
FlyWeightFactory factory=new FlyWeightFactory();
FlyWeight f=factory.getFlyWeight("test");
f.set("123");
FlyWeight f2=factory.getFlyWeight("test");
f2.operation(); //out : "123"
}
}


//在Test中,我们在f上做了标记123,结果在f2中得到,说明f和f2是同一个对象,即是达到了共享。
原创粉丝点击