8种设计模式:

2018-06-07  本文已影响17人  3Q竹林
主要介绍

单例设计模式,代理设计模式,观察者设计模式,模板模式(Template), 适配器模式,装饰模式(Decorator),命令模式(Command),策略模式(Strategy);(单代命 观模装适)。

1. 单例模式:

一般包括:懒汉式单例、饿汉式单例、登记式单例。

//懒汉式单例类.在第一次调用的时候实例化自己   
public class Singleton {  
  private Singleton() {}  
  private static Singleton single=null;  
  //静态工厂方法   
  public static Singleton getInstance() {  
       synchronized (Singleton.class) {    
             if (singleton == null) {    
                singleton = new Singleton();   
             }             
      }    
      return singleton;   
  }  
}

//静态内部类时,不需要用同步
public class Singleton {    
  private static class LazyHolder {    
     private static final Singleton INSTANCE = new Singleton();    
  }    
  private Singleton (){}    
  public static final Singleton getInstance() {    
     return LazyHolder.INSTANCE;    
  }    
}   

//饿汉式单例类.在类初始化时,已经自行实例化   
public class Singleton1 {  
  private Singleton1() {}  
  private static final Singleton1 single = new Singleton1(); 
  //静态工厂方法   
  public static Singleton1 getInstance() {  
      return single;  
  }  
}

//登记式单例
  /*实际上维护了一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从Map直接返回,对于没有登记的,则先登记,然后返回。它用的比较少且麻烦,另外其实内部实现还是用的饿汉式单例,这里忽略。*/

2. 代理模式

是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。

3. 命令模式

是指为了实现调用者角色与接收者角色之间,没有任何依赖关系,即完全解耦。

//通用Receiver类
public abstract class Receiver {
    public abstract void doSomething();
}

//具体Receiver类
public class ConcreteReciver1 extends Receiver{ 
    //每个接收者都必须处理一定的业务逻辑 
    public void doSomething(){ } 
} 
public class ConcreteReciver2 extends Receiver{ 
    //每个接收者都必须处理一定的业务逻辑 
    public void doSomething(){ } 
}

//抽象Command类
public abstract class Command {
    public abstract void execute();
}

//具体的Command类
public class ConcreteCommand1 extends Command { 
    //对哪个Receiver类进行命令处理 
    private Receiver receiver; 
    //构造函数传递接收者 
    public ConcreteCommand1(Receiver _receiver){
        this.receiver = _receiver; 
    } 

    //必须实现一个命令 
    public void execute() { 
    //业务处理 
        this.receiver.doSomething(); 
    } 
} 

public class ConcreteCommand2 extends Command { 
    //哪个Receiver类进行命令处理 
    private Receiver receiver; 
    //构造函数传递接收者 
    public ConcreteCommand2(Receiver _receiver){
        this.receiver = _receiver; 
    } 
    //必须实现一个命令 
    public void execute() { 
        //业务处理 
        this.receiver.doSomething();
    } 
}

//调用者Invoker类
public class Invoker {
    private Command command;
    
    public void setCommand(Command _command){
        this.command = _command;
    }
    
    public void action() {
        this.command.execute();
    }
}

//场景类
public class Client {
    public static void main(String[] args){
        Invoker invoker = new Invoker();
        Receiver receiver = new ConcreteReceiver1();
        
        Command command = new ConcreteCommand1(receiver);
        invoker.setCommand(command);
        invoker.action();
    }
}
4. 观察者设计模式

是指在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。

/***
 * 抽象被观察者接口
 * 声明了添加、删除、通知观察者方法
 * @author jstao
 *
 */
public interface Observerable {
    
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
    
}

//定义一个抽象观察者接口
/***
 * 抽象观察者
 * 定义了一个update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。
 * @author jstao
 *
 */
public interface Observer {
    public void update(String message);
}

//定义被观察者,实现了Observerable接口,对Observerable接口的三个方法进行了具体实现,同时有一个List集合,用以保存注册的观察者,等需要通知观察者时,遍历该集合即可。

/**
 * 被观察者,也就是微信公众号服务
 * 实现了Observerable接口,对Observerable接口的三个方法进行了具体实现
 * @author jstao
 *
 */
public class WechatServer implements Observerable {
   
    //注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
    private List<Observer> list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void registerObserver(Observer o) {
        
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty())
            list.remove(o);
    }

    //遍历
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服务更新消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }

}

//定义具体观察者,微信公众号的具体观察者为用户User
/**
 * 观察者
 * 实现了update方法
 * @author jstao
 *
 */
public class User implements Observer {
    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
}

5. 模板模式

定义一个操作中算法的骨架,而将一些步骤延迟到子类中。也就是说,要在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。

public abstract class DodishTemplate {  //模板类
    /**
     * 具体的整个过程
     */
    protected void dodish(){
        this.preparation();
        this.doing();
        this.carriedDishes();
    }
    /**
     * 备料
     */
    public abstract void preparation();
    /**
     * 做菜
     */
    public abstract void doing();
    /**
     * 上菜
     */
    public abstract void carriedDishes ();
}


public class EggsWithTomato extends DodishTemplate{ //具体实现类

    @Override
    public void preparation() {
        System.out.println("洗并切西红柿,打鸡蛋。");
    }

    @Override
    public void doing() {
        System.out.println("鸡蛋倒入锅里,然后倒入西红柿一起炒。");
    }

    @Override
    public void carriedDishes() {
        System.out.println("将炒好的西红寺鸡蛋装入碟子里,端给客人吃。");
    }

}


//代码中调用:
 DodishTemplate eggsWithTomato = new EggsWithTomato();
 eggsWithTomato.dodish();
6. 装饰模式

也叫做包装模式,是结构型设计模式之一。目的是为了给一个类或对象增加行为。可以是继承的一种替代。

//先抽象组件类:
public abstract class Component {
    public abstract void operate();
}
组件的一个具体实现类,也就是被装饰者者:

public class ConcreteComponent extends Component {
    @Override
    public void operate() {
        System.out.println("被装饰者的操作");
    }
}

//抽象的装饰者,持有一个被装饰者的引用:
public abstract class Decorator extends Component { 
    private Component component;

    public Decorator(Component component) { //采用传参方式,替代继承类的方式,这样区分开继承利于后期管理
        this.component = component;
    }

    @Override
    public void operate() {
        component.operate();
    }
}


//具体的两个装饰者,拓展功能:
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operate() {
        operateA();
        super.operate();
        operateB();
    }

    private void operateA(){
        System.out.println("装饰者A在被装饰者的操作之前加些操作");
    }
    private void operateB(){
        System.out.println("装饰者A在被装饰者的操作之前后加些操作");
    }
}
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    @Override
    public void operate() {
        operateA();
        super.operate();
        operateB();
    }

    private void operateA(){
        System.out.println("装饰者B在被装饰者的操作之前加些操作");
    }
    private void operateB(){
        System.out.println("装饰者B在被装饰者的操作之前后加些操作");
    }
}


//客户端调用:
public class Client {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA(component);
        ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB(component);

        concreteDecoratorA.operate();
        concreteDecoratorB.operate();
    }
}
7. 适配器模式

将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,可以理解成转换器。 例子:https://blog.csdn.net/lmb55/article/details/51008762

8. 策略模式

定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法"独立"于使用它的客户而独立变化。

public interface CalPrice {
    //根据原价返回一个最终的价格
    Double calPrice(Double orgnicPrice);
}

public class Orgnic implements CalPrice {

    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice;
    }
}

public class Vip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.9;
    }
}

public class SuperVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.8;
    }
}

public class GoldVip implements CalPrice {
    @Override
    public Double calPrice(Double orgnicPrice) {
        return orgnicPrice * 0.7;
    }
}

public class Player {
    private Double totalAmount = 0D;//客户在鹅厂消费的总额
    private Double amount = 0D;//客户单次消费金额
    private CalPrice calPrice = new Orgnic();//每个客户都有一个计算价格的策略,初始都是普通计算,即原价

    //客户购买皮肤,就会增加它的总额
    public void buy(Double amount) {
        this.amount = amount;
        totalAmount += amount;
        if (totalAmount > 30000) {//30000则改为金牌会员计算方式
            calPrice = new GoldVip();
        } else if (totalAmount > 20000) {//类似
            calPrice = new SuperVip();
        } else if (totalAmount > 10000) {//类似
            calPrice = new Vip();
        }
    }

    //计算客户最终要付的钱
    public Double calLastAmount() {
        return calPrice.calPrice(amount);
    }
}

//调用
Player player = new Player();
player.buy(5000D);
System.out.println("玩家需要付钱:" + player.calLastAmount());

上一篇下一篇

猜你喜欢

热点阅读