设计模式

创建型模式

Factory--工厂模式

简单工厂模式

创建工厂对象,然后通过条件获取相应的对象,这种方式健壮性差,如果输入的条件字符串不符合要求则不能获取到相应的对象。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

class PetFactory {
    public Pet getPet(String name) {
        if(name.equals("Dog")) {
            return new Dog();
        }else if (name.equals("Cat")) {
            return new Cat();
        }else {
            // 条件都不符合,创建默认对象
            return new Dog();
        }
    }
}

public class FactoryModel {
    public static void main(String[] args) {
        PetFactory petFactory = new PetFactory();
        Pet dog = petFactory.getPet("Dog");
        dog.eat();
    }
}

对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,提供多个工厂方法,分别创建对象。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

class PetFactory {
    public Pet getDog() {
        return new Dog();
    }

    public Pet getCat() {
        return new Cat();
    }
}

public class FactoryModel {
    public static void main(String[] args) {
        PetFactory petFactory = new PetFactory();
        Pet dog = petFactory.getDog();
        dog.eat();
    }
}
多个工厂方法模式

有时需要新增一个或多个种类,例如新加一个Bird动物,可实现动物接口,以及实现工厂类,这样就不需要去修改其他的接口了。

interface Pet {
    public void eat();
}

class Dog implements Pet {

    @Override
    public void eat() {
        System.out.print("Dog is eat");
    }
}

class Cat implements Pet {

    @Override
    public void eat() {
        System.out.print("Cat is eat");
    }
}

interface Factory {
    public Pet produce();
}

class DogFactory implements Factory {

    @Override
    public Pet produce() {
        return new Dog();
    }
}

class CatFactory implements Factory {

    @Override
    public Pet produce() {
        return new Cat();
    }
}

public class AbstractFactoryModel {
    public static void main(String[] args) {
        Factory factory = new DogFactory();
        Pet dog = factory.produce();
        dog.eat();
    }
}

AbstractFactory--抽象工厂模式

抽象工厂模式中弥补了工厂模式的不足(一个工厂只能生产一种产品)。工厂模式中一个工厂只能生产一种产品,而抽象工厂可以生产多个。

package AbstractFactoryModel;

interface Pet {
    public void eat();
}

interface Dog extends Pet {
}

interface Cat extends Pet{
}

class ChinaDog implements Dog {

    @Override
    public void eat() {
        System.out.println("China dog is eat...");
    }
}

class ForeignDog implements Cat {

    @Override
    public void eat() {
        System.out.println("Foreign dog is eat...");
    }
}

class ChinaCat implements Cat {

    @Override
    public void eat() {
        System.out.println("China cat is eat...");
    }
}

class ForeignCat implements Cat {

    @Override
    public void eat() {
        System.out.println("Foreign cat is eat...");
    }
}

interface PetFactory {
    public Pet produceDog();
    public Pet produceCat();
}

class ChinaFactory implements PetFactory {

    @Override
    public Pet produceDog() {
        return new ChinaDog();
    }

    @Override
    public Pet produceCat() {
        return new ChinaCat();
    }
}

class ForeignFactory implements PetFactory {

    @Override
    public Pet produceDog() {
        return new ForeignDog();
    }

    @Override
    public Pet produceCat() {
        return new ForeignCat();
    }
}

public class AbstractFactoryModel {
    public static void main(String[] args) {
        PetFactory chinaFactory = new ChinaFactory();
        Pet dog = chinaFactory.produceDog();
        dog.eat();
    }
}

Singleton--单例模式

单例对象能保证在一个JVM中,该对象只有一个实例存在。

饿汉模式

直接创建该对象,不是懒加载。

class SingletonModel {
    private static SingletonModel singleton = new SingletonModel();

    private SingletonModel() {

    }

    public static SingletonModel getInstance() {
        return singleton;
    }
}


public class HungarySingletonModel {
    public static void main(String[] args) {
        SingletonModel instance = SingletonModel.getInstance();
    }
}
懒汉模式

只有需要用到该对象才创建。使用双重检查锁机制。在还没有该对象的时候,第一次判断为空,此时可能会有多个线程进入到这,也就是说多个线程都判断为空成立,此时某个线程获得锁资源,待该线程释放锁,会有下一个线程获得锁资源,如果不再次判断是否为空,则之后的线程会再次创建对象,此时第一个获得锁资源的线程已经创建了对象,则再次判断可以避免再次创建对象。

class SingletonModel {
    private static SingletonModel singleton = null;

    private SingletonModel() {

    }

    public static SingletonModel getInstance() {
        if (singleton == null) {
            synchronized (singleton) {
                if (singleton == null) {
                    singleton = new SingletonModel();
                }
            }
        }
        return singleton;
    }
}

public class LazySingletonModel {
    public static void main(String[] args) {
        SingletonModel instance = SingletonModel.getInstance();
    }
}

Builder--建造者模式

将一个复杂对象的构建与它的属性分离,使得同样的构建过程可以创建不同的属性。
目的是将构建复杂对象的过程和它的属性解耦。
类比房子,房子是个对象,而屋顶和地基都是房子的属性,而建造屋顶和地基都有单独的方法实现。
工厂模式关注的是创建单个产品,而建造者模式则关注创建复杂的对象,包含多个部分。

class House {
    private String roof;
    private String foundation;

    public String getRoof() {
        return roof;
    }

    public void setRoof(String roof) {
        this.roof = roof;
    }

    public String getFoundation() {
        return foundation;
    }

    public void setFoundation(String foundation) {
        this.foundation = foundation;
    }
}

interface Builder {
    void buildRoof();
    void buildFoundation();
    House createHouse();
}

class HouseBuilder implements Builder {
    private House house;

    public HouseBuilder(House house) {
        this.house = house;
    }

    @Override
    public void buildRoof() {
        this.house.setRoof("roof");
    }

    @Override
    public void buildFoundation() {
        this.house.setFoundation("foundation");
    }

    @Override
    public House createHouse() {
        return this.house;
    }


}
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public House construct() {
        builder.buildRoof();
        builder.buildFoundation();
        return builder.createHouse();
    }

}

public class BuilderModel {
    public static void main(String[] args) {
        House house = new House();
        Builder builder = new HouseBuilder(house);
        Director director = new Director(builder);
        house = director.construct();
        System.out.println(house);
    }
}

Prototype--原型模式

定义:用原型实例通过拷贝创建新的对象。Prototype模式允许一个对象再创建另外一个可定制的对象,根部无需知道任何创建的细节,工作原理:通过将一个原型对象传给创建方法,从而通过对原型对象的拷贝来创建新的对象。

浅复制
class Pet implements Cloneable{
    private String name;
    private int age;

    public Pet(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class PrototypeModel {
    public static void main(String[] args) {
        Pet pet = new Pet("Tom", 1);
        System.out.println("Pet'address is " + pet.toString());

        try {
            Pet clone_pet = (Pet) pet.clone();
            System.out.println("Clone pet'address is " + clone_pet.toString());

        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
深复制
package PrototypeModel;

import java.io.*;

class Dog implements Serializable{
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void introduce() {
        System.out.println(this.name + "'age is " + this.age);
    }

    public Dog clone() {
        try {
            // 创建一个字节数组输出流用来保存序列化后对象的字节
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            // 创建一个对象输出流
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            // 将对象写出到之前创建的字节输出流中
            objectOutputStream.writeObject(this);
            // 将字节数组输出流转化为字节数组
            byte[] bytes = byteArrayOutputStream.toByteArray();

            // 创建一个字节输入流,将上面的对象字节写入到流中
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
            // 创建一个对象输入流,将字节输入流包装
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            // 从流中将对象写出来,强转为该对象类型
            Dog dog = (Dog) objectInputStream.readObject();
            return dog;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

public class DeepPrototypeModel {
    public static void main(String[] args) {
        Dog dog = new Dog("Tom", 2);
        dog.introduce();
        System.out.println(dog.toString());
        Dog cloneDog = dog.clone();
        cloneDog.introduce();
        System.out.println(cloneDog.toString());
    }
}

结构型模式

Adapter--适配器模式

类适配器

通过继承来实现适配器功能

interface Usb {
    void isUsb();
}

interface Ps2 {
    void isPs2();
}

class Usber implements Usb {

    @Override
    public void isUsb() {
        System.out.println("Usb接口");
    }
}

class Adapter extends Usber implements Ps2 {

    @Override
    public void isPs2() {
        System.out.println("Ps2接口");
    }
}

public class ClassAdapter {
    public static void main(String[] args) {
        Adapter p = new Adapter();
        p.isPs2();
        p.isUsb();
    }
}

对象适配器

通过对象实例来实现适配器功能

interface Usb {
    void isUsb();
}

interface Ps2 {
    void isPs2();
}

class Usber implements Usb {

    @Override
    public void isUsb() {
        System.out.println("Usb接口");
    }
}

class Adapter implements Ps2 {
    private Usber usb;

    public Adapter(Usber usb) {
        this.usb = usb;
    }

    @Override
    public void isPs2() {
        System.out.println("Ps2接口");
    }

    public void isUsb() {
        this.usb.isUsb();
    }
}

public class ObjectAdapter {
    public static void main(String[] args) {
        Adapter adapter = new Adapter(new Usber());
        adapter.isPs2();
        adapter.isUsb();
    }
}

接口适配器

如果需要定义一个类,且只需要接口中部分方法,可以使用抽象类去实现接口,然后使用该类去继承抽象类,就可以去重写部分方法了。

interface People {
    void eat();
    void run();
}

abstract class Adapter implements People {
    @Override
    public void eat() {

    }

    @Override
    public void run() {

    }
}

class Baby extends Adapter {
    @Override
    public void eat() {
        System.out.println("I can eat!");
    }
}

class InterfaceAdapterModel {
    public static void main(String[] args) {
        Baby baby = new Baby();
        baby.eat();
    }
}

Bridge--桥接模式

桥接模式就是把事物和其具体实现分开,使他们可以各自独立的变化。像常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换。

interface JDBC {
    void connect();
}

class mysql implements JDBC {

    @Override
    public void connect() {
        System.out.println("connect mysql...");
    }
}

class oracle implements JDBC {

    @Override
    public void connect() {
        System.out.println("connect oracle...");
    }
}

abstract class Bridge {
    private JDBC jdbc;

    public void connect() {
        jdbc.connect();
    }

    public JDBC getJdbc() {
        return jdbc;
    }

    public void setJdbc(JDBC jdbc) {
        this.jdbc = jdbc;
    }
}

class MyBridge extends Bridge {
    @Override
    public void connect() {
        super.connect();
    }
}

public class BridgeModel {
    public static void main(String[] args) {
        Bridge bridge = new MyBridge();

        JDBC jdbc = new mysql();
        bridge.setJdbc(jdbc);
        bridge.connect();

        JDBC oracle = new oracle();
        bridge.setJdbc(oracle);
        bridge.connect();
    }
}

Composite--组合模式

将对象以树形组织起来,以达成“部分-整体”的层次结构,使得客户端对单个对象 和组合对象的使用具有一致性。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容

  • 清晨,拉开窗帘想看看预报中的重度雾霾,却被眼前的景色惊呆了~屋顶、地面被一层白雪覆盖了,更难以想象的是楼前的树枝变...
    槑头槑脑儿阅读 328评论 0 2
  • Hello, everyone. Long time no see. Today, weshare some En...
    Game0ver阅读 423评论 1 3
  • 好久未联系的同学今天聊了起来 聊了很多 大家都非常想念彼此,我有时候做梦都会梦到以前高中时,真的很美好,现在想起来...
    Rose啊阅读 112评论 0 1