设计模式

观察者模式使用场景:一个对象对其他对象有影响的时候

  1. 汇率对出口成本或进口利率或者公司利润率影响。
  2. 根据上下课铃声,老师和学生进行的事件不同。
    在这里插入图片描述
    在这里插入图片描述
package observer;
import java.util.*;
public class BellEventTest
{
    public static void main(String[] args)
    {
        BellEventSource bell=new BellEventSource();    //铃(事件源)    
        bell.addPersonListener(new TeachEventListener()); //注册监听器(老师)
        bell.addPersonListener(new StuEventListener());    //注册监听器(学生)
        bell.ring(true);   //打上课铃声
        System.out.println("------------");   
        bell.ring(false);  //打下课铃声
    }
}
//铃声事件类:用于封装事件源及一些与事件相关的参数
class RingEvent extends EventObject
{   
    private static final long serialVersionUID=1L;
    private boolean sound;    //true表示上课铃声,false表示下课铃声
    public RingEvent(Object source,boolean sound)
    {
        super(source);
        this.sound=sound;
    }   
    public void setSound(boolean sound)
    {
        this.sound=sound;
    }
    public boolean getSound()
    {
        return this.sound;
    }
}
//目标类:事件源,铃
class BellEventSource
{    
    private List<BellEventListener> listener; //监听器容器
    public BellEventSource()
    { 
        listener=new ArrayList<BellEventListener>();        
    }
    //给事件源绑定监听器 
    public void addPersonListener(BellEventListener ren)
    { 
        listener.add(ren); 
    }
    //事件触发器:敲钟,当铃声sound的值发生变化时,触发事件。
    public void ring(boolean sound)
    {
        String type=sound?"上课铃":"下课铃";
        System.out.println(type+"响!");
        RingEvent event=new RingEvent(this, sound);     
        notifies(event);    //通知注册在该事件源上的所有监听器                
    }   
    //当事件发生时,通知绑定在该事件源上的所有监听器做出反应(调用事件处理方法)
    protected void notifies(RingEvent e)
    { 
        BellEventListener ren=null; 
        Iterator<BellEventListener> iterator=listener.iterator(); 
        while(iterator.hasNext())
        { 
            ren=iterator.next(); 
            ren.heardBell(e); 
        } 
    }
}
//抽象观察者类:铃声事件监听器
interface  BellEventListener extends EventListener
{
    //事件处理方法,听到铃声
    public void heardBell(RingEvent e);
}
//具体观察者类:老师事件监听器
class TeachEventListener implements BellEventListener
{
    public void heardBell(RingEvent e)
    {        
        if(e.getSound())
        {
            System.out.println("老师上课了...");           
        }
        else
        {
            System.out.println("老师下课了...");   
        }          
    }
}
//具体观察者类:学生事件监听器
class StuEventListener implements BellEventListener
{
    public void heardBell(RingEvent e)
    {        
        if(e.getSound())
        {
            System.out.println("同学们,上课了...");           
        }
        else
        {
            System.out.println("同学们,下课了...");   
        }          
    }
}

**观察者模式扩展,**通过 java.util.Observable 类和 java.util.Observer 接口定义了观察者模式,只要实现它们的子类就可以编写观察者模式实例。

  1. void addObserver(Observer o) 方法:用于将新的观察者对象添加到向量中。
  2. void notifyObservers(Object arg) 方法:调用向量中的所有观察者对象的 update。方法,通知它们数据发生改变。通常越晚加入向量的观察者越先得到通知。
  3. void setChange() 方法:用来设置一个 boolean 类型的内部标志位,注明目标对象发生了变化。当它为真时,notifyObservers() 才会通知观察者。
  4. Observer 接口是抽象观察者,它监视目标对象的变化,当目标对象发生变化时,观察者得到通知,并调用 void update(Observable o,Object arg) 方法,进行相应的工作。
package observer;
import java.util.Observer;
import java.util.Observable;
public class CrudeOilFutures
{
    public static void main(String[] args)
    {
        OilFutures oil=new OilFutures();
        Observer bull=new Bull(); //多方
        Observer bear=new Bear(); //空方
        oil.addObserver(bull);
        oil.addObserver(bear);
        oil.setPrice(10);
        oil.setPrice(-8);
    }
}
//具体目标类:原油期货
class OilFutures extends Observable
{
    private float price;   
    public float getPrice()
    {
        return this.price; 
    }
    public void setPrice(float price)
    {
        super.setChanged() ;  //设置内部标志位,注明数据发生变化 
        super.notifyObservers(price);    //通知观察者价格改变了 
        this.price=price ; 
    }
}
//具体观察者类:多方
class Bull implements Observer
{   
    public void update(Observable o,Object arg)
    {
        Float price=((Float)arg).floatValue();
        if(price>0)
        {
            System.out.println("油价上涨"+price+"元,多方高兴了!");
        }
        else
        {
            System.out.println("油价下跌"+(-price)+"元,多方伤心了!");
        }
    }
}
//具体观察者类:空方
class Bear implements Observer
{   
    public void update(Observable o,Object arg)
    {
        Float price=((Float)arg).floatValue();
        if(price>0)
        {
            System.out.println("油价上涨"+price+"元,空方伤心了!");
        }
        else
        {
            System.out.println("油价下跌"+(-price)+"元,空方高兴了!");
        }
    }
}

油价上涨10.0元,空方伤心了!
油价上涨10.0元,多方高兴了!
油价下跌8.0元,空方高兴了!
油价下跌8.0元,多方伤心了!

代理模式

  1. 真实主题与代理主题一一对应,增加真实主题也要增加代理。
  2. 设计代理以前真实主题必须事先存在,不太灵活。采用动态代理模式可以解决以上问题,如 SpringAOP,其结构图如图 4 所示。
    在这里插入图片描述

单例模式应用:

  1. 用懒汉式单例模式模拟产生美国当今总统对象。分析:在每一届任期内,美国的总统只有一人,所以本实例适合用单例模式实现,图 2 所示是用懒汉式单例实现的结构图。
  2. 在应用场景中,某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
  3. 当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。
  4. 当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。

在这里插入图片描述

public class SingletonLazy
{
    public static void main(String[] args)
    {
        President zt1=President.getInstance();
        zt1.getName();    //输出总统的名字
        President zt2=President.getInstance();
        zt2.getName();    //输出总统的名字
        if(zt1==zt2)
        {
           System.out.println("他们是同一人!");
        }
        else
        {
           System.out.println("他们不是同一人!");
        }
    }
}
class President
{
    private static volatile President instance=null;    //保证instance在所有线程中同步
    //private避免类在外部被实例化
    private President()
    {
        System.out.println("产生一个总统!");
    }
    public static synchronized President getInstance()
    {
        //在getInstance方法上加同步
        if(instance==null)
        {
               instance=new President();
        }
        else
        {
           System.out.println("已经有一个总统,不能产生新总统!");
        }
        return instance;
    }
    public void getName()
    {
        System.out.println("我是美国总统:特朗普。");
    }  
}

抽象工厂模式:
在这里插入图片描述
应用实例:
农场中除了像畜牧场一样可以养动物,还可以培养植物,如养马、养牛、种菜、种水果等,所以本实例比前面介绍的畜牧场类复杂,必须用抽象工厂模式来实现。

package AbstractFactory;
import java.awt.*;
import javax.swing.*;
public class FarmTest
{
    public static void main(String[] args)
    {
        try
        {          
            Farm f;
            Animal a;
            Plant p;
            f=(Farm) ReadXML.getObject();
            a=f.newAnimal();
            p=f.newPlant();
            a.show();
            p.show();
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}
//抽象产品:动物类
interface Animal
{
    public void show();
}
//具体产品:马类
class Horse implements Animal
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Horse()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("动物:马"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/A_Horse.jpg"));
        p1.add(l1);       
        jf.pack();       
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭 
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//具体产品:牛类
class Cattle implements Animal
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Cattle() {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("动物:牛"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/A_Cattle.jpg"));
        p1.add(l1);       
        jf.pack();       
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭 
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//抽象产品:植物类
interface Plant
{
    public void show();
}
//具体产品:水果类
class Fruitage implements Plant
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Fruitage()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("植物:水果"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/P_Fruitage.jpg"));
        p1.add(l1);       
        jf.pack();       
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭 
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//具体产品:蔬菜类
class Vegetables implements Plant
{
    JScrollPane sp;
    JFrame jf=new JFrame("抽象工厂模式测试");
    public Vegetables()
    {
        Container contentPane=jf.getContentPane();
        JPanel p1=new JPanel();
        p1.setLayout(new GridLayout(1,1));
        p1.setBorder(BorderFactory.createTitledBorder("植物:蔬菜"));
        sp=new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1=new JLabel(new ImageIcon("src/P_Vegetables.jpg"));
        p1.add(l1);       
        jf.pack();       
        jf.setVisible(false);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//用户点击窗口关闭 
    }
    public void show()
    {
        jf.setVisible(true);
    }
}
//抽象工厂:农场类
interface Farm
{
    public Animal newAnimal();
    public Plant newPlant();
}
//具体工厂:韶关农场类
class SGfarm implements Farm
{
    public Animal newAnimal()
    {
        System.out.println("新牛出生!");
        return new Cattle();
    }
    public Plant newPlant()
    {
        System.out.println("蔬菜长成!");
        return new Vegetables();
    }
}
//具体工厂:上饶农场类
class SRfarm implements Farm
{
    public Animal newAnimal()
    {
        System.out.println("新马出生!");
        return new Horse();
    }
    public Plant newPlant()
    {
        System.out.println("水果长成!");
        return new Fruitage();
    }
}

适配器模式应用场景:

  1. 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
  2. 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

在这里插入图片描述

package adapter;
//目标接口
interface TwoWayTarget
{
    public void request();
}
//适配者接口
interface TwoWayAdaptee
{
    public void specificRequest();
}
//目标实现
class TargetRealize implements TwoWayTarget
{
    public void request()
    {       
        System.out.println("目标代码被调用!");
    }
}
//适配者实现
class AdapteeRealize implements TwoWayAdaptee
{
    public void specificRequest()
    {       
        System.out.println("适配者代码被调用!");
    }
}
//双向适配器
class TwoWayAdapter  implements TwoWayTarget,TwoWayAdaptee
{
    private TwoWayTarget target;
    private TwoWayAdaptee adaptee;
    public TwoWayAdapter(TwoWayTarget target)
    {
        this.target=target;
    }
    public TwoWayAdapter(TwoWayAdaptee adaptee)
    {
        this.adaptee=adaptee;
    }
    public void request()
    {
        adaptee.specificRequest();
    }
    public void specificRequest()
    {       
        target.request();
    }
}
//客户端代码
public class TwoWayAdapterTest
{
    public static void main(String[] args)
    {
        System.out.println("目标通过双向适配器访问适配者:");
        TwoWayAdaptee adaptee=new AdapteeRealize();
        TwoWayTarget target=new TwoWayAdapter(adaptee);
        target.request();
        System.out.println("-------------------");
        System.out.println("适配者通过双向适配器访问目标:");
        target=new TargetRealize();
        adaptee=new TwoWayAdapter(target);
        adaptee.specificRequest();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值