03-結(jié)構(gòu)型模式

1. 適配器模式*

適配器模式:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作

SpringMVC中的HandlerAdapter就使用了適配器模式

1.1 類適配器模式

// 客戶希望使用的接口:destination
interface MyStack {
    void pop();
}

// 被適配者:source
class MyList {
    public void removeFirst() {
        System.out.println("名叫removeFirst的出棧");
    }
}

// 類適配器:通過繼承Source類励稳、實(shí)現(xiàn)Destination接口窍株,完成Source->Destination的適配
class Adapter extends MyList implements MyStack {
    @Override
    public void pop() {
        this.removeFirst();
    }
}

public class AdapterClient {
    public static void main(String[] args) {
        MyStack stack = new Adapter();
        stack.pop();
    }
}

1.2 對象適配器模式

// 客戶希望使用的接口:destination
interface MyStack {
    void pop();
}

// 被適配者:source
class MyList {
    public void removeFirst() {
        System.out.println("名叫removeFirst的出棧");
    }
}

/**
 * 對象適配器*:通過復(fù)合晕换,除了滿足“用戶期待接口”筐喳,還降低了代碼間的不良耦合
 * 通過復(fù)合Source類法绵、實(shí)現(xiàn)Destination接口转质,完成Source->Destination的適配
 */
class Adapter implements MyStack {
    private MyList myList = new MyList();

    @Override
    public void pop() {
        myList.removeFirst();
    }
}

public class AdapterClient {
    public static void main(String[] args) {
        MyStack stack = new Adapter();
        stack.pop();
    }
}

1.3 缺省適配器模式

// 客戶希望使用的接口:destination
interface ListStack {
    void pop();

    void removeFirst();
}

/**
 * 缺省適配器:當(dāng)不需要使用一個(gè)接口的全部方法時(shí)佩抹,
 * 可以設(shè)計(jì)一個(gè)抽象類實(shí)現(xiàn)接口的所有方法叼风,但有的方法可以做成空方法,
 * 那么該抽象類的子類可以選擇性的重寫父類的某些方法
 */
abstract class Adapter implements ListStack {
    @Override
    public void pop() {
    }

    @Override
    public void removeFirst() {
    }
}

// 被適配者:source
class MyList extends Adapter {
    @Override
    public void removeFirst() {
        System.out.println("我只需要removeFirst()方法");
    }
}

public class AdapterClient {
    public static void main(String[] args) {
        ListStack list = new MyList();
        list.removeFirst();
        // Source類也可以用匿名內(nèi)部類來代替
        ListStack stack = new Adapter() {
            @Override
            public void pop() {
                System.out.println("我只需要pop()方法");
            }
        };
        stack.pop();
    }
}

2. 橋接模式

橋接模式:將抽象部分與它的實(shí)現(xiàn)部分分離棍苹,使它們可以獨(dú)立地變化无宿,又稱為柄體模式或接口模式

橋接模式模式基于單一職責(zé)原則,通過使用封裝枢里、聚合及繼承等方式讓不同的類承擔(dān)不同的職責(zé)

橋梁模式所涉及的角色:

  1. 實(shí)現(xiàn)化角色(Implementor):這個(gè)角色給出實(shí)現(xiàn)化角色的接口
  2. 具體實(shí)現(xiàn)化角色(Concrete Implementor):這個(gè)角色給出實(shí)現(xiàn)化角色接口的具體實(shí)現(xiàn)
  3. 抽象化角色(Abstraction):抽象化給出的定義孽鸡,并保存一個(gè)對實(shí)現(xiàn)化對象的引用
  4. 修正抽象化角色(Refined Abstraction):抽象化角色的子類蹂午,改變和修正父類對抽象化的定義

實(shí)現(xiàn)化角色應(yīng)當(dāng)只給出底層操作,而抽象化角色應(yīng)當(dāng)只給出基于底層操作的更高一層的操作

// 實(shí)現(xiàn)化角色:顏色
interface Color {
    void showColor();
}

// 具體實(shí)現(xiàn)化角色:黑色
class Black implements Color {
    @Override
    public void showColor() {
        System.out.print("黑色的");
    }
}

// 具體實(shí)現(xiàn)化角色:白色
class White implements Color {
    @Override
    public void showColor() {
        System.out.print("白色的");
    }
}

// 抽象化角色:在內(nèi)部聚合一個(gè)實(shí)現(xiàn)化角色
abstract class Animal {
    Color color;

    public void show() {
        this.color.showColor();
    }
}

// 修正抽象化角色:狗
class Dog extends Animal {
    @Override
    public void show() {
        super.show();
        System.out.println("狗汪汪叫");
    }
}

// 修正抽象化角色:貓
class Cat extends Animal {
    @Override
    public void show() {
        super.show();
        System.out.println("貓喵喵叫");
    }
}

public class BridgeClient {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.color = new Black();
        // 黑色的狗汪汪叫
        dog.show();

        Cat cat = new Cat();
        cat.color = new White();
        // 白色的貓喵喵叫
        cat.show();
    }
}

3. 裝飾模式*

裝飾模式:在不必改變原類文件和使用繼承的情況下彬碱,動態(tài)地給一個(gè)對象添加一些額外的職責(zé)豆胸;它是通過創(chuàng)建一個(gè)包裝對象,也就是裝飾來包裹真實(shí)的對象巷疼。

裝飾模式特點(diǎn):

  1. 裝飾對象和真實(shí)對象有相同的接口
  2. 裝飾對象包含一個(gè)真實(shí)對象的引用
  3. 裝飾對象接受所有來自客戶端的請求晚胡,裝飾對象可以在轉(zhuǎn)發(fā)這些請求以前或以后增加一些附加功能

裝飾模式所涉及的角色:

  1. 抽象構(gòu)件角色(Component):給出一個(gè)抽象接口,以規(guī)范準(zhǔn)備接收附加責(zé)任的對象
  2. 具體構(gòu)件角色(Concrete Component):定義一個(gè)將要接收附加責(zé)任的類
  3. 裝飾角色(Decorator):持有一個(gè)構(gòu)件(Component)對象的實(shí)例嚼沿,并實(shí)現(xiàn)一個(gè)與抽象構(gòu)件接口一致的接口
  4. 具體裝飾角色(Concrete Decorator):負(fù)責(zé)給構(gòu)件對象添加上附加的責(zé)任

裝飾模式簡化:

  1. 如果只有一個(gè)具體構(gòu)件角色而沒有抽象構(gòu)件角色時(shí)估盘,可以讓裝飾角色繼承具體構(gòu)件角色
  2. 如果只有一個(gè)具體裝飾角色時(shí),可以將裝飾角色和具體裝飾角色合并

裝飾模式適用情況:

  1. 需要擴(kuò)展一個(gè)類的功能骡尽,或給一個(gè)類添加附加職責(zé)
  2. 需要動態(tài)的給一個(gè)對象添加功能遣妥,這些功能可以再動態(tài)的撤銷
  3. 需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能
  4. 當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時(shí)

Java的IO流就采用了裝飾模式

裝飾者模式原理類圖:

// 抽象構(gòu)件角色
interface IO {
    void copy();
}

// 具體構(gòu)件角色
class MyIO implements IO {
    @Override
    public void copy() {
        System.out.println("拷貝");
    }
}

// 裝飾角色
class Decorator implements IO {
    IO io;

    public Decorator(IO io) {
        this.io = io;
    }

    @Override
    public void copy() {
        io.copy();
    }
}

// 具體裝飾角色:BufferedIO
class BufferedIO extends Decorator {
    public BufferedIO(IO io) {
        super(io);
    }

    @Override
    public void copy() {
        super.copy();
        addBuffered();
    }

    public void addBuffered() {
        System.out.println("擁有緩沖功能");
    }
}

// 具體裝飾角色:LineNumberIO
class LineNumberIO extends Decorator {
    public LineNumberIO(IO io) {
        super(io);
    }

    @Override
    public void copy() {
        super.copy();
        addLineNumber();
    }

    public void addLineNumber() {
        System.out.println("擁有操作行號功能");
    }
}

public class DecoratorClient {
    public static void main(String[] args) {
        IO io = new Decorator(new MyIO());
        io = new BufferedIO(io);
        io = new LineNumberIO(io);
        // 調(diào)用過程類似遞歸,一層一層裝飾
        io.copy();
        /**結(jié)果:
         * 拷貝
         * 擁有緩沖功能
         * 擁有操作行號功能
         */
    }
}

4. 組合模式

組合模式:將對象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)爆阶。Composite使得用戶對單個(gè)對象和組合對象的使用具有一致性燥透。

組合模式所涉及的角色:

  1. Component:是組合中的對象聲明接口沙咏,在適當(dāng)?shù)那闆r下辨图,實(shí)現(xiàn)所有類共有接口的默認(rèn)行為。聲明一個(gè)接口用于訪問和管理Component子部件
  2. Leaf:在組合中表示葉子結(jié)點(diǎn)對象
  3. Composite:定義有枝節(jié)點(diǎn)行為肢藐,用來存儲子部件故河,在Component接口中實(shí)現(xiàn)與子部件有關(guān)操作,如增加(add)和刪除(remove)等

java.util.HashMap就使用了組合模式

import java.util.ArrayList;
import java.util.List;

abstract class Component {
    String name;

    public Component(String name) {
        this.name = name;
    }

    void add(Component component) {
        throw new UnsupportedOperationException();
    }

    void remove(Component component) {
        throw new UnsupportedOperationException();
    }

    abstract void display(int depth);
}

class Composite extends Component {
    List<Component> componentList = new ArrayList<>();

    public Composite(String name) {
        super(name);
    }

    @Override
    public void add(Component component) {
        componentList.add(component);
    }

    @Override
    public void remove(Component component) {
        componentList.remove(component);
    }

    @Override
    public void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.name);
        for (Component component : componentList) {
            component.display(depth + 3);
        }
    }
}

class Leaf extends Component {
    public Leaf(String name) {
        super(name);
    }

    @Override
    public void display(int depth) {
        StringBuilder sb = new StringBuilder("");
        for (int i = 0; i < depth; i++) {
            sb.append("-");
        }
        System.out.println(new String(sb) + this.name);
    }
}

public class CompositeClient {
    public static void main(String[] args) {
        Composite root = new Composite("數(shù)計(jì)學(xué)院");
        Composite jsj = new Composite("計(jì)算機(jī)專業(yè)");
        Composite wl = new Composite("網(wǎng)絡(luò)專業(yè)");
        jsj.add(new Leaf("設(shè)計(jì)模式"));
        jsj.add(new Leaf("數(shù)據(jù)結(jié)構(gòu)"));
        wl.add(new Leaf("網(wǎng)絡(luò)原理"));
        root.add(jsj);
        root.add(wl);
        root.display(0);
        /**結(jié)果:類似DOM樹
         * 數(shù)計(jì)學(xué)院
         * ---計(jì)算機(jī)專業(yè)
         * ------設(shè)計(jì)模式
         * ------數(shù)據(jù)結(jié)構(gòu)
         * ---網(wǎng)絡(luò)專業(yè)
         * ------網(wǎng)絡(luò)原理
         */
    }
}

5. 外觀模式

外觀模式(過程模式):為子系統(tǒng)中的一組接口提供一個(gè)一致的界面吆豹,F(xiàn)acade模式定義了一個(gè)高層接口鱼的,這個(gè)接口使得子系統(tǒng)更加容易使用

org.apache.ibatis.session.Configuration類的newMetaObject方法就使用了外觀模式

// 子系統(tǒng):CPU
class CPU {
    public void freeze() {
    }

    public void jump() {
    }

    public void execute() {
    }
}

// 子系統(tǒng):Memory
class Memory {
    public void load() {
    }
}

// 外觀類:為子系統(tǒng)提供一個(gè)共同的對外接口
class Computer {
    CPU cpu = new CPU();
    Memory memory = new Memory();

    public void startComputer() {
        cpu.freeze();
        memory.load();
        cpu.jump();
        cpu.execute();
    }
}

// 客戶端:通過一個(gè)外觀接口讀寫子系統(tǒng)中各接口的數(shù)據(jù)資源
public class FacadeClient {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.startComputer();
    }
}

6. 享元模式

享元模式:運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對象。使用共享物件來盡可能減少內(nèi)存使用量以及分享資訊給盡可能多的相似物件

享元模式的兩個(gè)狀態(tài):

  1. 內(nèi)蘊(yùn)狀態(tài)存儲在享元內(nèi)部痘煤,不會隨環(huán)境的改變而有所不同凑阶,是可以共享的
  2. 外蘊(yùn)狀態(tài)是不可以共享的,它隨環(huán)境的改變而改變的衷快,因此外蘊(yùn)狀態(tài)是由客戶端來保持

享元模式所涉及的角色:

  1. 抽象享元角色(FlyWeight):是具體享元的抽象宙橱,同時(shí)定義出對象的內(nèi)蘊(yùn)狀態(tài)和外蘊(yùn)狀態(tài)的接口或?qū)崿F(xiàn)
  2. 具體享元角色(ConcreteFlyWeight):實(shí)現(xiàn)抽象角色規(guī)定的方法。如果存在內(nèi)蘊(yùn)狀態(tài)蘸拔,就負(fù)責(zé)為內(nèi)蘊(yùn)狀態(tài)提供存儲空間
  3. 享元工廠角色(FlyWeightFactory):用于構(gòu)建一個(gè)池容器师郑,同時(shí)提供從池中獲取對象方法;這個(gè)角色的實(shí)現(xiàn)是共享的關(guān)鍵
  4. 客戶端角色(Client):維護(hù)對所有享元對象的引用调窍,而且還需要存儲對應(yīng)的外蘊(yùn)狀態(tài)

享元模式能夠解決重復(fù)對象的內(nèi)存浪費(fèi)的問題宝冕,享元模式的經(jīng)典應(yīng)用場景就是池技術(shù)

java.lang.Integer類的valueOf方法就采用了享元模式

import java.util.HashMap;

// 外蘊(yùn)狀態(tài)
class OuterStatus {
    String outerState;

    public OuterStatus(String outerState) {
        this.outerState = outerState;
    }
}

// 抽象享元角色
interface Flyweight {
    void use(OuterStatus outerStatus);
}

// 具體享元角色
class ConcreteFlyWeight implements Flyweight {
    // 共享部分,內(nèi)蘊(yùn)狀態(tài)
    String type;

    public ConcreteFlyWeight(String type) {
        this.type = type;
    }

    @Override
    public void use(OuterStatus outerStatus) {
        System.out.println("具體享元:" + type + "\t外蘊(yùn)狀態(tài):" + outerStatus.outerState);
    }
}

// 享元工廠角色
class FlyWeightFactory {
    HashMap<String, Flyweight> pool = new HashMap<>();

    public Flyweight getFlyweight(String type) {
        if (!pool.containsKey(type)) {
            pool.put(type, new ConcreteFlyWeight(type));
        }
        return pool.get(type);
    }

    public int getFlyweightSize() {
        return pool.size();
    }
}

// 客戶端角色
public class FlyweightClient {
    public static void main(String[] args) {
        FlyWeightFactory flyWeightFactory = new FlyWeightFactory();
        Flyweight sqlPool1 = flyWeightFactory.getFlyweight("數(shù)據(jù)庫連接池");
        sqlPool1.use(new OuterStatus("url"));
        Flyweight sqlPool2 = flyWeightFactory.getFlyweight("數(shù)據(jù)庫連接池");
        sqlPool2.use(new OuterStatus("driver"));
        int flyweightSize = flyWeightFactory.getFlyweightSize();
        System.out.println(flyweightSize);
    }
}

7. 代理模式*

代理模式概念:為其他對象提供一種代理以控制對這個(gè)對象的訪問邓萨。在某些情況下地梨,一個(gè)對象不適合或者不能直接引用另一個(gè)對象菊卷,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用

代理模式組成:

  1. 抽象角色:通過接口或抽象類聲明真實(shí)角色實(shí)現(xiàn)的業(yè)務(wù)方法
  2. 真實(shí)角色:實(shí)現(xiàn)抽象角色,定義真實(shí)角色所要實(shí)現(xiàn)的業(yè)務(wù)邏輯湿刽,供代理角色調(diào)用
  3. 代理角色:實(shí)現(xiàn)抽象角色的烁,是真實(shí)角色的代理,通過真實(shí)角色的業(yè)務(wù)邏輯方法來實(shí)現(xiàn)抽象方法诈闺,并可以附加自己的操作

7.1 靜態(tài)代理

靜態(tài)代理是在程序運(yùn)行前就已經(jīng)存在代理類的字節(jié)碼文件渴庆,代理類和委托類的關(guān)系在運(yùn)行前就確定了

真實(shí)角色和代理角色實(shí)現(xiàn)同一個(gè)接口

// 抽象角色
interface MyConnection {
    void createStatement();

    void close();
}

// 真實(shí)角色
class JdbcConnection implements MyConnection {
    @Override
    public void createStatement() {
        System.out.println("獲取執(zhí)行SQL的對象");
    }

    @Override
    public void close() {
        System.out.println("關(guān)閉連接");
    }
}

// 代理角色
class ProxyConnection implements MyConnection {
    JdbcConnection jdbcConnection = new JdbcConnection();

    @Override
    public void createStatement() {
        jdbcConnection.createStatement();
    }

    @Override
    public void close() {
        System.out.println("歸還連接");
    }
}

public class ProxyClient {
    public static void main(String[] args) {
        MyConnection connection = new ProxyConnection();
        connection.createStatement();
        connection.close();
    }
}

7.2 JDK動態(tài)代理

動態(tài)代理是在實(shí)現(xiàn)階段不用關(guān)心代理類,而在運(yùn)行階段才指定哪一個(gè)對象

JDK動態(tài)代理是基于接口的動態(tài)代理:要求被代理類至少實(shí)現(xiàn)一個(gè)接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 抽象角色
interface MyConnection {
    void createStatement();

    void close();
}

// 真實(shí)角色
class JdbcConnection implements MyConnection {
    @Override
    public void createStatement() {
        System.out.println("獲取執(zhí)行SQL的對象");
    }

    @Override
    public void close() {
        System.out.println("關(guān)閉連接");
    }
}

// JDK動態(tài)代理
class JDKProxyConnectionFactory {
    MyConnection connection = new JdbcConnection();

    // 動態(tài)生成代理角色
    public MyConnection getProxyInstance() {
        return (MyConnection) Proxy.newProxyInstance(JdbcConnection.class.getClassLoader(), new Class[]{MyConnection.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object object = null;
                // 如果是close方法雅镊,就增強(qiáng)該方法
                if ("close".equals(method.getName())) {
                    System.out.println("歸還連接");
                } else {
                    // 調(diào)用真實(shí)角色的方法
                    object = method.invoke(connection, args);
                }
                return object;
            }
        });
    }
}

public class ProxyClient {
    public static void main(String[] args) {
        JDKProxyConnectionFactory jdkProxyConnectionFactory = new JDKProxyConnectionFactory();
        MyConnection connection = jdkProxyConnectionFactory.getProxyInstance();
        connection.createStatement();
        connection.close();
    }
}

7.3 CGLib動態(tài)代理

CGLib(Code Generation Library)比java.lang.reflect.Proxy類更強(qiáng)的在于它不僅可以接管接口類的方法襟雷,還可以接管普通類的方法

CGLib動態(tài)代理是基于子類的動態(tài)代理:被代理類可以不必實(shí)現(xiàn)接口,它是在內(nèi)存中構(gòu)建一個(gè)子類對象從而實(shí)現(xiàn)對目標(biāo)對象功能擴(kuò)展仁烹,因此真實(shí)角色類不能被final修飾

CGLib的底層是通過使用Java字節(jié)碼操作框架ASM來轉(zhuǎn)換字節(jié)碼并生成新的類

使用CGLib需導(dǎo)入的jar包耸弄,如:aspectjweaver-1.8.7.jar(Spring的AOP依賴)或cglib-2.2.2.jar+asm-3.3.1.jar

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

// 真實(shí)角色
class JdbcConnection {
    public void createStatement() {
        System.out.println("獲取執(zhí)行SQL的對象");
    }

    public void close() {
        System.out.println("關(guān)閉連接");
    }
}

// CGLib動態(tài)代理
class CGLibProxyConnectionFactory {
    JdbcConnection jdbcConnection = new JdbcConnection();

    // 獲取一個(gè)代理角色
    public JdbcConnection getProxyInstance() {
        // 1. 創(chuàng)建Enhancer對象
        Enhancer enhancer = new Enhancer();
        // 2. 設(shè)置父類(要代理的類)
        enhancer.setSuperclass(jdbcConnection.getClass());
        // 3. 設(shè)置回調(diào)函數(shù)
        enhancer.setCallback(new MethodInterceptor() {
            /**
             * 參數(shù)說明:
             * Object:表示要進(jìn)行增強(qiáng)的對象
             * Method:表示攔截的方法
             * Object[]:表示參數(shù)列表,基本數(shù)據(jù)類型需要傳入其包裝類型
             * MethodProxy:表示對方法的代理
             */
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object object = null;
                // 如果是close方法卓缰,就增強(qiáng)該方法
                if ("close".equals(method.getName())) {
                    System.out.println("歸還連接");
                } else {
                    // 調(diào)用真實(shí)角色的方法
                    object = method.invoke(jdbcConnection, args);
                    System.out.println("---------------------");
                    // 調(diào)用真實(shí)角色的方法
                    methodProxy.invokeSuper(obj, args);
                }
                return object;
            }
        });
        // 4. 創(chuàng)建代理對象
        return (JdbcConnection) enhancer.create();
    }
}

public class ProxyClient {
    public static void main(String[] args) {
        CGLibProxyConnectionFactory cgLibProxyConnectionFactory = new CGLibProxyConnectionFactory();
        JdbcConnection jdbcConnection = cgLibProxyConnectionFactory.getProxyInstance();
        jdbcConnection.createStatement();
        jdbcConnection.close();
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末计呈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子征唬,更是在濱河造成了極大的恐慌捌显,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件总寒,死亡現(xiàn)場離奇詭異扶歪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)摄闸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門善镰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人年枕,你說我怎么就攤上這事炫欺。” “怎么了熏兄?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵品洛,是天一觀的道長。 經(jīng)常有香客問我霍弹,道長毫别,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任典格,我火速辦了婚禮岛宦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耍缴。我一直安慰自己砾肺,他們只是感情好挽霉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著变汪,像睡著了一般侠坎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裙盾,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天实胸,我揣著相機(jī)與錄音,去河邊找鬼番官。 笑死庐完,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徘熔。 我是一名探鬼主播门躯,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼酷师!你這毒婦竟也來了讶凉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤山孔,失蹤者是張志新(化名)和其女友劉穎懂讯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饱须,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡域醇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年台谊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蓉媳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锅铅,死狀恐怖酪呻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盐须,我是刑警寧澤玩荠,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贼邓,受9級特大地震影響阶冈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜塑径,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一女坑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧统舀,春花似錦匆骗、人聲如沸劳景。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盟广。三九已至,卻和暖如春瓮钥,著一層夾襖步出監(jiān)牢的瞬間筋量,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工碉熄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毛甲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓具被,卻偏偏與公主長得像玻募,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子一姿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容