1. 程式人生 > >設計模式 結構型模式

設計模式 結構型模式

適配模式

在下圖中可以看出,Adaptee類並沒有sampleOperation2()方法,而客戶端則期待這個方法。為使客戶端能夠使用Adaptee類,提供一箇中間環節,即類Adapter,把Adaptee的API與Target類的API銜接起來。Adapter與Adaptee是繼承關係。
在這裡插入圖片描述

interface Target{
	// Adaptee有這個方法
	void sampleOperation1();
	// Adaptee沒有這個方法
	void sampleOperation2();
}

class Adaptee{
	public void sampleOperation1
(){} } class Adapter extends Adaptee implements Target{ public void sampleOperation2(){} }

這好比ADSL,使用者想通過電話線上網,但是電話線不能直接接到電腦上,但使用者就是想通過電話線上網,所以引入了調變解調器,調變解調器就是做介面卡的作用。

組合模式

組合模式就比較簡單了,以樹型結構組成的層次關係,忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。
在這裡插入圖片描述
以檔案和資料夾為例

abstract class Compoent{}

class File extends
Compoent{ private String fileName; } class FileFolder extends Compoent{ private List<Compoment> files; private String fileFolderName; public void scan(){ for(component f:files){ if(f instanceof File){ System.out.println("File "+((File) f).filename); }
else if(f instanceof Folder){ Folder e = (Folder)f ; System.out.println("Folder "+e.foldername); e.scan(); } } } }

橋接模式

在這裡插入圖片描述它的主要特點是把抽象(Abstraction)與行為實現(Implementation)分離開來,從而可以保持各部分的獨立性以及應對他們的功能擴充套件。

1.Client 呼叫端

這是Bridge模式的呼叫者。

2.抽象類(Abstraction)

抽象類介面(介面這貨抽象類)維護隊行為實現(implementation)的引用。它的角色就是橋接類。

3.Refined Abstraction

這是Abstraction的子類。

4.Implementor

行為實現類介面(Abstraction介面定義了基於Implementor介面的更高層次的操作)

5.ConcreteImplementor

Implementor的子類

interface Implementor{
	// 定義其實現類必須實現的介面
	public void operation();
}

public class ConcreateImplementorA implements Implementor{
	public void operation(){}
}
public class ConcreateImplementorB implements Implementor{
	public void operation(){}
}

// 橋接類
public abstract class Abstract{
	private Implementor implementor;
	public void setTmplementor(Implementor implementor){
		this.implementor = implementor;
	}
	public void getTmplementor(){
		return this.implementor;
	}
	protected viod operation(){
		this.implementor.operation();
	}
}

public class RefinedAbstraction extends Abstract{
	protected void operation(){
		super.getImplementor.operation();
	}
}

裝飾者模式

裝飾模式指的是在不必改變原類檔案和使用繼承的情況下,動態地擴充套件一個物件的功能。它是通過建立一個包裝物件,也就是裝飾來包裹真實的物件。

interface Source{ void method();}
public class Decorator implements Source{
    // 這是真實的物件
    private Source source ;
    public void decotate1(){
        System.out.println("decorate");
    }
    // 這是包裝類提供的包裝方法
    @Override
    public void method() {
        decotate1();
        source.method();
    }
}

代理模式

裝飾模式應該為所裝飾的物件增強功能;代理模式對代理的物件施加控制,並不提供物件本身的增強功能。
客戶端通過代理類訪問,代理類實現具體的實現細節,客戶只需要使用代理類即可實現操作。

interface BuyHouse{ void buyHosue();}

class BuyHouseImpl implements BuyHouse{
    @Override
    public void buyHosue() {
    }
}

class Proxy implements BuyHouse{
    private BuyHouse buyHosue;

    public void setBuyHouse(final BuyHouse buyHouse){
	this.buyHouse = buyHouse;
    }
    @Override
    public void buyHosue() {
        System.out.println("買房前準備");
        buyHosue.buyHosue();
        System.out.println("買房前準備");
    }
}

外觀模式

用一個大外部介面統一操作各個子物件


public interface Shape {
   void draw();
}


public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Rectangle::draw()");
   }
}

public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Square::draw()");
   }
}

public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Circle::draw()");
   }
}

public class ShapeMaker {
   private Shape circle;
   private Shape rectangle;
   private Shape square;
 
   public ShapeMaker() {
      circle = new Circle();
      rectangle = new Rectangle();
      square = new Square();
   }
 
   public void drawCircle(){
      circle.draw();
   }
   public void drawRectangle(){
      rectangle.draw();
   }
   public void drawSquare(){
      square.draw();
   }
}

public class FacadePatternDemo {
   public static void main(String[] args) {
      ShapeMaker shapeMaker = new ShapeMaker();
 
      shapeMaker.drawCircle();
      shapeMaker.drawRectangle();
      shapeMaker.drawSquare();      
   }
}

享元模式

使用共享物件的方法,用來儘可能減少記憶體使用量以及分享資訊。通常使用工廠類輔助,例子中使用一個HashMap類進行輔助判斷,資料池中是否已經有了目標例項,如果有,則直接返回,不需要多次建立重複例項。

abstract class flywei{ }

public class Flyweight extends flywei{
    Object obj ;
    public Flyweight(Object obj){
        this.obj = obj;
    }
}

class  FlyweightFactory{
    private HashMap<Object,Flyweight> data;

    public FlyweightFactory(){ data = new HashMap<>();}

    public Flyweight getFlyweight(Object object){
        if ( data.containsKey(object)){
            return data.get(object);
        }else {
            Flyweight flyweight = new Flyweight(object);
            data.put(object,flyweight);
            return flyweight;
        }
    }
}