设计模式_慕课网

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014267209/article/details/52524922

设计模式:

1.定义:

是一套被反复使用.多数人只晓的.经过分类编目的.代码设计经验的总结

2.目的:

使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性

3.分类(23种):

创建型模式(5种):单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式
结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

一.单例模式(Singleton)

1.作用:

    保证整个应用程序中某个实例有且只有一个

2.常见的单例对象:

    配置文件.工具类.线程池.缓存.日志对象等

3.分类:

    饿汉模式:   类加载后便会创建实例,不管用户是否获取
    懒汉模式:成员变量只声明不实例化,在第一个用户获取该实例的时候才会创建

4.实现过程

    1.将构造方法私有化,不允许外部直接创建对象
    2.自己创建类的唯一实例,并且使用私有的静态的成员变量 private static
    3.对象暴露一个用于获取实例的静态方法 public static

5.饿汉模式和懒汉模式的区别

    饿汉模式加载类的时候比较慢,但是获取比较快,而且是线程安全的
    懒汉模式加载类的时候比较快,但是获取比较慢,而且是线程不安全

二.工厂模式

1.概念:

->实例化对象,用工厂方法代替new操作
->工厂模式包括工厂方法模式和抽象工厂模式
->抽象工厂模式是工厂方法模式的扩展

2.意图:

->定义一个接口来创建对象,但是让子类来决定哪些类需要实例化
->工厂方法把实例化的工作推迟到子类中去实现

3.应用场景:

->有一组类似的对象需要创建
->在编码时不能预见需要创建哪种类的实例
->系统需要考虑扩展性, 不应依赖于产品类实例如何被创建.组合和表达的细节

4.设计思想:

->尽量松耦合,一个对象的依赖对象的变化与本身无关
->具体产品与客户端剥离,责任分割

5.好处:

-> 系统可以在不修改具体工厂角色的情况下引进新的产品
-> 客户端不必关心对象如何创建,明确职责
-> 更好的理解面向对象的原则 面向接口编程 而不是面向实现编程

6.常见应用:

JDBC.Spring BeanFactory.

7.工厂方法模式和抽象工厂模式对比

-> 工厂模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广
-> 工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构
-> 工厂模式只是一个抽象的产品类,而抽象工厂模式有多个抽象产品类

三.观察者模式

1.介绍:

对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖与它的对象都得到通知并自动更新

2. 结构:

Subject:对象
Observe:观察者

3. 步骤:

第一:是目标对象的定义
第二:是具体的目标对象的定义
第三:观察者的接口定义
第四:观察者的具体实现 
实例代码:


----------对象
 public class WeatherSubject {
    private List<Observer> observers = new ArrayList<>();

    // 添加观察者
    public void attach(Observer observer) {
        observers.add(observer);
    }

    // 删除观察者
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    protected void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(this);
        }
    }
}


----------对象实现类
public class WeatherSubjectImpl extends WeatherSubject {

    private String weatherContent;

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
        this.notifyObservers(); // 值改变的时候触发通知方法
    }

}


----------观察者接口
public interface Observer {
    void update(WeatherSubject weather);
}


----------观察者接口的实现类
public class ObserverImpl implements Observer {
    private String observerName;
    private String weatherContent;
    private String remindThing;

    @Override
    public void update(WeatherSubject weather) {
        weatherContent = ((WeatherSubjectImpl) weather).getWeatherContent();
        System.out.println(observerName + "收到了" + weatherContent + "," + remindThing);
    }

    public String getObserverName() {
        return observerName;
    }

    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
    }

    public String getRemindThing() {
        return remindThing;
    }

    public void setRemindThing(String remindThing) {
        this.remindThing = remindThing;
    }
}


----------观察者模式测试类
public class Client {
    public static void main(String[] args) {
        // 1.创建目标
        WeatherSubjectImpl weather = new WeatherSubjectImpl();

        // 2.创建观察者
        ObserverImpl observerGirl = new ObserverImpl();
        observerGirl.setObserverName("女朋友");
        observerGirl.setRemindThing("使我们的第一次约会,地点街心公园,不见不散哦~");

        ObserverImpl observerMum = new ObserverImpl();
        observerMum.setObserverName("老妈");
        observerMum.setRemindThing("是一个购物的好日子,明天去天虹扫货");

        // 3.注册观察者
        weather.attach(observerGirl);
        weather.attach(observerMum);

        // 4.目标发布天气
        weather.setWeatherContent("明天天气晴朗,蓝天白云,天气28度");
    }
}

4.分类:

推模型:按需将内容作为update的参数推送给观察者,会使观察者无法复用
拉模型:通常是将this传递给观察者,可以适用各种情况

5.可以使用Java自带的观察者信息

----------观察者类,实现Observer
public class WeatherObserver implements Observer {

    private String observerName;

    @Override
    public void update(Observable o, Object arg) {
        System.out.println(observerName + "收到了消息,目标推送过来的是" + arg);
        System.out.println(observerName + "收到了消息,主动拉到" + ((WeatherSubject) o).getContent());
    }

    public String getObserverName() {
        return observerName;
    }

    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }

}


----------目标类,实现Observale
//天气目标的具体实现类
public class WeatherSubject extends Observable {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;

        this.setChanged();
        this.notifyObservers(content);//推模式
//      this.notifyObservers();//拉模式
    }

}

----------测试类
public static void main(String[] args) {
        WeatherSubject weather = new WeatherSubject();

        WeatherObserver girlObserver = new WeatherObserver();
        girlObserver.setObserverName("女朋友:");

        WeatherObserver mumObserver = new WeatherObserver();
        mumObserver.setObserverName("老妈:");

        weather.addObserver(girlObserver);
        weather.addObserver(mumObserver);

        weather.setContent("天气晴朗,气温28度!");
    }

6.什么情况下使用观察者模式

1.当一个抽象模型有两个方面,其中一个方便的操作依赖于另一个方面的状态变化
2.如果在更改一个对象的时候,需要同事连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变
3.当一个对象必须通知其他的对象,但是你又希望这个对象和其他被它通知的对象是松散耦合的.

猜你喜欢

转载自blog.csdn.net/u014267209/article/details/52524922