IT

设计模式

2020-08-27  本文已影响0人  chs_sandy

分类

创建型

创建对象时,不再直接实例化对象;而是根据特定场景,由程序来确定创建对象的方式,从而保证更高的性能、更好的架构优势。创建型模式主要有简单工厂模式(并不是23种设计模式之一)、工厂方法、抽象工厂模式、单例模式、生成器模式和原型模式。

结构型

用于帮助将对个对象组织成更大的结构。结构型模式主要有适配器模式、桥接模式、组合器模式、装饰器模式、门面模式、享元模式和代理模式。

行为型

用于帮助系统间各对象的通信,以及如何控制复杂系统中的流程。行为模式主要有命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板模式和访问者模式。

单例模式

如果一个类始终只能创建一个实例,则这个类被称为单例类,这种模式就被称为单例模式。
Spring推荐将所有业务逻辑组件、DAO组件、数据源组件等配置成单例的行为方式,因为这些组件无需保存任何用户状态。
为了保证一个类只能产生一个实例,程序不能允许自由创建该类的对象,只需要使用private修饰该类的构造器,从而将该类的构造器隐藏起来。同时提供一个public方法作为该类的访问点,用于创建该类的对象,且该方法必须使用static修饰(因为调用该方法之前还不存在对象,因此调用该方法的不可能是对象,只能是类)。除此之外,该类还必须缓存已经创建的对象,否则该类无法知道是否曾经创建过实例,也就无法保证只创建一个实例。为此该类需要使用一个静态属性来保存曾经创建的实例,且该属性需要被静态方法访问,所以该属性也应使用static修饰。

class Singleton {
   //使用一个类变量缓存曾经创建的实例
   private static Singleton instance;
   // 将构造器使用private修饰,隐藏该构造器
   private Singleton(){}
   //提供一个静态方法,用于返回Singleton实例
   //该方法可以加入自定义的控制,保证只产生一个Singleton对象
   public static Singleton getInstance(){
       //如果instance为null,表明不曾创建Singleton对象
       //如果instance不为null,则表明已创建了Singleton对象,将不会执行该方法
       if(instance == null){
           instance = new Singleton();
       }
       return instance;
   }
}

工厂

  • 简单工厂
  • 工厂方法
  • 冲向工厂
    定义一个Factory专门用于生产类对象。使用方通过Factory调用对应的类对象,将使用者和类对象解耦,由统一工厂耦合。如果需要更改类对象,不需要更改工厂的调用者。
    如果工厂直接生产被调用对象,那就是简单工厂模式;如果工厂生产了工厂对象,那就是会升级成抽象工厂模式。

代理模式

InvokationHandler实现

public class MyInvokationHandler implements InvocationHandler {
   //需要被代理的对象
   private Object target;

   public void setTarget(Object target) {
       this.target = target;
   }

   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       TxUtil tx = new TxUtil();
       tx.beginTx();

       Object result = method.invoke(target,args);
       tx.endTx();
       return result;
   }
}
public class MyProxyFactory {

   //为指定target生成动态代理对象
   public static Object getProxy(Object target) throws Exception{
       //创建一个MyInvokationHandler对象
       MyInvokationHandler handler = new MyInvokationHandler();

       //为MyInvokationHandler设置target对象
       handler.setTarget(target);
       //创建并返回一个动态代理
       return Proxy.newProxyInstance(target.getClass().getClassLoader() , >target.getClass().getInterfaces(),handler);
   }
}

命令模式

思考一种场景,某个方法需要完成某一个功能,完成这个功能的参数要求可以变化,具体执行的代码也可以变化,即需要把“处理行为”也作为一个参数传入方法。

public interface Command {
   void process(int[] target);
}
public class ProcessArray {
   public void each(int[] target,Command cmd){
       cmd.process(target);
   }
}
  public class CommandTest {
    public static void main(String[] args) {
       ProcessArray pa = new ProcessArray();
       int[] target = {3,-4,6,4};
       pa.each(target, new Command() {
           @Override
           public void process(int[] target) {
               for(int tmp : target){
                   System.out.println("迭代输出目标数组的元素:"+ tmp);
               }
           }
       });
   }
}

策略模式

思考一种场景,某书店需要提供打折场景(vip折扣,旧书兑换折扣。。。)
其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。

桥接模式

假如有一个饭店提供菜单:牛肉面、猪肉面...选择添加辣椒时:无辣、微辣、中辣...
此时可以选择桥接模式(把变化的部分抽象出来)然后使得变化部分与主类分离开来;通过组合满足业务的需要。

观察者模式

观察者模式定义了对象间的一对多依赖关系,让一个或者多个观察者对象观察一个主题对象。当主题对象的状态发生变化时,系统能通知所有的依赖于次对象的观察者对象,从而使得观察者对象能够自动更新。

观察者模式主要的4个角色:

  • 被观察者的抽象基类。一般有java.util.Observable提供。
  • 观察者接口 一般由java.util.Observer提供
  • 被观察者实现类 Product
  • 观察者实现类
//被观察者
public class Product extends Observable {

    //定义两个成员变量
    private String name;
    private double price;

    public Product(){}

    public Product(String name,double price){
        this.name = name;
        this.price = price;
    }

    public String getName(){
        return name;
    }

    //当程序调用name的setter方法来修改Product的name成员变量时,程序自然触发该对象上注册的所有观察者
    public void setName(String name){
        this.name = name;
        this.setChanged();
        notifyObservers(name);
    }

    public double getPrice(){
        return price;
    }

    public void setPrice(double price){
        this.price = price;
        this.setChanged();
        notifyObservers(price);
    }
}

//观察者实现
public class NameObserver implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        if( arg instanceof String ){
            String name = (String) arg;
            JFrame f = new JFrame("观察者");
            JLabel l = new JLabel("名称改变为:" + name);
            f.add(l);
            f.pack();
            f.setVisible(true);
            System.out.println("名称观察者:" + o + "物品名称已经改变为:" + name);
        }
    }
}
//注册观察者至被观察者
public class Main {
    public static void main(String[] args) {
        Product p = new Product("电视剧",176);

        NameObserver no = new NameObserver();
        PriceObserver po = new PriceObserver();

//        p.registObserver(no);
//        p.registObserver(po);
        p.addObserver(no);
        p.addObserver(po);

        p.setName("书桌");
        p.setPrice(345f);

    }
}

上一篇下一篇

猜你喜欢

热点阅读