zoukankan      html  css  js  c++  java
  • 策略模式-观察者模式-装饰者模式-工厂模式-单例模式

    算是最近学设计模式(HEAD FIRST设计模式)的一个总结吧,力求用最精简的代码说明其设计本质。

    第一个模式:策略模式

    代码:

     1 interface refuel {
     2     public void fuelUp();
     3 }
     4 
     5 
     6 class car {
     7     refuel fuelType;
     8 
     9     public void setFuelType(refuel type) {
    10         this.fuelType = type;
    11     }
    12 
    13     public void fuelUp() {
    14         fuelType.fuelUp();
    15     }
    16 
    17 }
    18 
    19 
    20 class fuelUpWith_93 implements refuel {
    21 
    22     @Override
    23     public void fuelUp() {
    24         System.out.println("Fueled up with No.93 gasoline");
    25     }
    26 
    27 }
    28 
    29 
    30 class fuelUpWith_97 implements refuel {
    31 
    32     @Override
    33     public void fuelUp() {
    34         System.out.println("Fueled up with No.97 gasoline");
    35     }
    36 
    37 }

    说明:汽车都需要加油,但是不同汽车加不同的油,通过让汽车持有一个具体实现加油算法的对象(通常向上转型为其接口),在汽车加油的时候直接调用这个接口,让其自己实现这种汽车加油的相关算法。

    设计思想:解耦合,这个设计模式最大的优点是:能保证复用所有相同的代码(只要你的汽车持有了其使用的汽油类型),又能保证当你需要一种新的实现的时候可以快速加入进去(写一种实现基础接口的算法实现)而不需要修改原有代码。

    第二个设计模式:观察者模式

    代码(JAVA内置实现):

     1 import java.util.Observable;
     2 import java.util.Observer;
     3 
     4 public class Main {
     5 
     6     public static void main(String[] args) {
     7         School highSchool = new School();
     8         Student Jack = new Student("Jack");
     9         Student Tom = new Student("Tom");
    10         Jack.register(highSchool);
    11         Tom.register(highSchool);
    12         highSchool.termBegins();
    13     }
    14 }
    15 
    16 
    17 class School extends Observable {
    18 
    19     public void termBegins() {
    20         this.setChanged();
    21         this.notifyObservers();
    22     }
    23 
    24 }
    25 
    26 
    27 class Student implements Observer {
    28 
    29     Observable o;
    30     String name;
    31 
    32     public Student(String name) {
    33         this.name = new String(name);
    34     }
    35 
    36     public void register(Observable o) {
    37         this.o = o;
    38         o.addObserver(this);
    39     }
    40 
    41     @Override
    42     public void update(Observable o, Object arg) {
    43         if (o instanceof School) {
    44             System.out.println(name + " go to schoole");
    45         }
    46     }
    47 
    48 }

    代码(手动实现):

     1 import java.util.ArrayList;
     2 
     3 public class Main {
     4 
     5     public static void main(String[] args) {
     6         Student Jack = new Student("Jack");
     7         Student Tom = new Student("Tom");
     8         School highSchool = new School();
     9         highSchool.register(Jack);
    10         highSchool.register(Tom);
    11         highSchool.termBegins();
    12     }
    13 }
    14 
    15 
    16 class School {
    17 
    18     ArrayList<Student> stuList = new ArrayList<Student>();
    19 
    20     public void register(Student stu) {
    21         stuList.add(stu);
    22     }
    23 
    24     public void termBegins() {
    25         this.notifyObservers();
    26         System.out.println("Welcome to school!");
    27     }
    28 
    29     private void notifyObservers() {
    30         for (Student stu : stuList) {
    31             stu.update();
    32         }
    33     }
    34 }
    35 
    36 
    37 class Student {
    38 
    39     String name;
    40 
    41     public Student(String name) {
    42         this.name = new String(name);
    43     }
    44 
    45     public void update() {
    46         System.out.println(name + " go to school");
    47     }
    48 
    49 }

    说明:把学生(观察者)对象交给学校(被观察者)。当学校开学时,一个一个去“通知”,让其持有的学生对象作出对应的反应。

    设计思想:当需要变化的时候通知观察者们。Swing组件中大量用到(反应鼠标点击消息等等)。其他没啥很特别的东西。

    第三个设计模式:装饰者模式
    代码:

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         coffee myCoffee = new Mocha(new Milk(new regularCoffee()));
     5         System.out.println(myCoffee.getName());
     6     }
     7 }
     8 
     9 
    10 interface coffee {
    11 
    12     public int getCost();
    13 
    14     public String getName();
    15 
    16 }
    17 
    18 
    19 class regularCoffee implements coffee {
    20 
    21     @Override
    22     public int getCost() {
    23         return 5; // 最最普通的一杯咖啡底价5元
    24     }
    25 
    26     @Override
    27     public String getName() {
    28         return "咖啡"; // 最最普通的咖啡
    29     }
    30 
    31 }
    32 
    33 
    34 abstract class coffeeDecorator implements coffee {
    35 
    36     coffee oriCoffee;
    37 
    38 }
    39 
    40 
    41 class Milk extends coffeeDecorator { // 牛奶,加牛奶的修饰器
    42 
    43     public Milk(coffee c) {
    44         this.oriCoffee = c;
    45     }
    46 
    47     @Override
    48     public int getCost() {
    49         return oriCoffee.getCost() + 3; // 加一份牛奶再加3元
    50     }
    51 
    52     @Override
    53     public String getName() {
    54         return "牛奶" + oriCoffee.getName(); // 加一份牛奶的话,名字上也要加一份牛奶前缀
    55     }
    56 
    57 }
    58 
    59 
    60 class Mocha extends coffeeDecorator { // 摩卡,加巧克力的修饰器
    61 
    62     public Mocha(coffee c) {
    63         this.oriCoffee = c;
    64     }
    65 
    66     @Override
    67     public int getCost() {
    68         return oriCoffee.getCost() + 4; // 加一份巧克力再叫4元
    69     }
    70 
    71     @Override
    72     public String getName() {
    73         return "摩卡" + oriCoffee.getName(); // 加一份巧克力的话,名字也加一个前缀
    74     }
    75 
    76 }

    说明:每一次新建一个装饰者(Mocha或者Milk或者你写的别的什么),都依赖于一个传入的参数(目前的咖啡),在这个基础上继续添加装饰。

    设计思想:一些类可能有自由组合的可能(比如咖啡),你很难一次把他们写全(从设计上也不应该如此),于是便应该用装饰者模式让使用者自己去搭配。每一次经过修饰就在传入参数的基础上进行修改。

    第四个设计模式:工厂模式

    首先要说的是工厂模式这个名字让人迷惑,因为很多模式好像都和工厂模式有关系:

    1,静态工厂模式 : 一般是说用静态方法写的简单工厂模式。

    2,简单工厂模式 :就是一个类,里面封装了某个类的构造方法,不仅调配构造参数,也许还有别的工作要做。

    3,工厂方法模式 :在工厂中定义一个创建对象的接口,但是让子类去实现(通过Abstract)具体的创建过程。(和模板方法模式有点像)

    4,抽象工厂模式 :提供一个接口,用来创建相关或依赖对象的家族。

    关于工厂方法模式和抽象工厂模式可以看:看这篇文章

    第五个设计模式:单例模式
    代码(饿汉模式):

     1 class Singleton {
     2 
     3     private static Singleton instance = new Singleton();
     4 
     5     private Singleton() {
     6 
     7     }
     8 
     9     public static Singleton getInstance() {
    10         return instance;
    11     }
    12 
    13 }

    说明:饿汉模式就是直接在类的静态字段中写上一个实例对象。由<clinit>方法自动在类加载结束的时候进行创建。JVM会保证类的加载线程安全,所以这种情况基本上不需要考虑多线程情况下的线程安全。但是问题还是有:生命周期不可以控制,这个类一加载就存在一个实例对象。

    代码(懒汉模式,双重检查模式+volatile):

     1 class Singleton {
     2 
     3     private volatile static Singleton instance;
     4 
     5     private Singleton() {
     6 
     7     }
     8 
     9     public static Singleton getInstance() {
    10         if (instance == null) {
    11             synchronized (Singleton.class) {
    12                 if (instance == null) {
    13                     return new Singleton();
    14                 }
    15             }
    16         }
    17         return instance;
    18     }
    19 }

    说明:看这篇文章的说明

    设计思想:很多类只需要有一个实例,也许只能有一个实例,当尝试获取多个实例时会返回相同一个实例对象(或者返回null或者报错)。

  • 相关阅读:
    Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程
    Python之路(第四十一篇)线程概念、线程背景、线程特点、threading模块、开启线程的方式
    Python之路(第四十篇)进程池
    Python之路(第三十九篇)管道、进程间数据共享Manager
    树莓派系列(第一篇):用python代码查看树莓派的温度、cpu使用率、内存占用情况
    Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型
    Python之路(第三十七篇)并发编程:进程、multiprocess模块、创建进程方式、join()、守护进程
    Python之路(第三十六篇)并发编程:进程、同步异步、阻塞非阻塞
    Python之路(第三十五篇) 并发编程:操作系统的发展史、操作系统的作用
    Netty入门(二)之PC聊天室
  • 原文地址:https://www.cnblogs.com/dsj2016/p/5785427.html
Copyright © 2011-2022 走看看