• 学习准备


    1、23种设计模式学习

    1> 适配器模式:类的适配、对象适配、接口适配

    * 类的适配

    source 待适配的类

    public class Source {

     

    public void method1(){

    System.out.println("this is original method");

    }

    }

     

    Targeter 适配后的类

    public interface Targeter {

     

    public void method1();

    public void method2();

    }

     

    Adapter适配器

    public class Adapter extends Source implements Targeter{

     

    @Override

    public void method2() {

    System.out.println("this is targetable method!");

    }

     

    }

    Test 测试类

    public class Test {

     

    public static void main(String[] args) {

    Targeter t = new Adapter();

    t.method1();

    t.method2();

    }

    }

     

    * 对象的适配

    适配器

    public class Adapter implements Targeter{

     

    public Source source;

     

    public Adapter(Source source) {

    this.source = source;

    }

     

    @Override

    public void method2() {

    System.out.println("this is targetable method!");

    }

     

    @Override

    public void method1() {

    source.method1();

     

    }

     

    }

     

    测试类

    public class Test {

     

    public static void main(String[] args) {

    Source s = new Source();

    Targeter t = new Adapter(s);

    t.method1();

    t.method2();

    }

    }

     

     

    *接口的适配

    主要是为了解决这类问题:一个接口有好多方法,有的类用不到这么多,如果实现该接口就要实现所有的方法,代码多,这种情况可以考虑接口的适配,用一个抽象类实现该接口,之后的类继承该抽象类,不与接口直接打交道

    抽象类:

    public abstract class Wrapper implements Targeter{

     

    @Override

    public void method1() {}

    @Override

    public void method2() {

    }

    }

     

    具体类

    public class SourceSub extends Wrapper{

     

    @Override

    public void method1() {

    System.out.println("this is method1");

    }

    }

     

    public class SourceSub2 extends Wrapper{

     

    @Override

    public void method2() {

    System.out.println("this is method2");

    }

    }

     

    测试类

    public class Test {

     

    public static void main(String[] args) {

    Wrapper w1 = new SourceSub();

    Wrapper w2 = new SourceSub2();

    w1.method1();

    w2.method2();

    }

    }

     

    2> 装饰模式

    适合:能用到某个方法,但这个方法不完整,可以用装饰模式来修饰这个方法

    被装饰类compennent

     

    public interface Compon {

     

    public void method();

    }

     

    public class Component implements Compon{

     

    @Override

    public void method(){

    System.out.println("this is original method");

    }

    }

     

    装饰类

    public class Decorator implements Compon{

     

    public Component c;

     

    public Decorator(Component c) {

    this.c = c;

    }

     

    @Override

    public void method(){

    System.out.println("before decorator");

    c.method();

    System.out.println("after decorator");

    }

    }

     

    测试类

    public class Test {

     

    public static void main(String[] args) {

    Component c =new Component();

    Decorator d = new Decorator(c);

    c.method();

    d.method();

    }

    }

     装饰模式的应用场景:
            ①需要扩展一个类的功能
            ②动态的为一个对象增加功能,而且还能动态撤销(继承做不到这一点,
    继承的功能都是静态的,不能动态删减)
            ③缺点:产生太多相似的对象,不易排错
     
    3> 单例模式
    单例模式有几种实现

    public class Singleton {

     

    private static Singleton instance = null;

     

    private Singleton() {

    }

     

    public static Singleton getInstance(){

    if(instance == null){

    instance = new Singleton();

    }

    return instance;

    }

    }

    缺点:在多线程环境下,不安全

     

     

    public class Singleton2 {

     

    private static Singleton2 instance = null;

     

    private Singleton2() {

    }

     

    public static synchronized Singleton2 getInstance() {

    if (instance == null) {

    instance = new Singleton2();

    }

    return instance;

    }

    }

     

    缺点:效率不高,每次调用该方法都要对该对象加锁

     

    private static Singleton3 instance = null;

     

    private Singleton3() {

    }

     

    public static Singleton3 getInstance(){

    if(instance == null){

    synchronized(instance){

    if(instance == null){

    instance = new Singleton3();

    }

    }

    }

    return instance;

    }

    }

    缺点:

    将synchronized关键字加在了内部,也就是说当调用的时候是不需要加锁的,只有在instance为null,并创建对象的时候才需要加锁,性能有一定的提升。但是,这样的情况,还是有可能有问题的,看下面的情况:在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就可能出错了,我们以A、B两个线程为例:

    a>A、B线程同时进入了第一个if判断

    b>A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

    c>由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。

    d>B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。

    e>此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。

    *比较完美

    public class Singleton4 {

     

    private Singleton4() {

    }

     

    private static class SingletonFactory{

    private static Singleton4 instance = new Singleton4();

    }

     

    public static Singleton4 getInstance(){

    return SingletonFactory.instance;

    }

    }

    单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。

     

    4>工厂方法模式

    普通工厂模式、多工厂模式、静态工厂模式 较简单,但违反开闭原则,即对扩展开放,对修改关闭,因为如果要扩展的话必须修改代码

     

    5>抽象工厂模式

    把工厂抽象,这样扩展的话,只要再实现抽象工厂增加类就可以,符合开闭原则

     

    6>建造者模式

    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性。

    [java] view plain copy
    1. public interface Sender {  
    2.     public void Send();  
    3. }  

    两个实现类:

    [java] view plain copy
     
    1. public class MailSender implements Sender {  
    2.     @Override  
    3.     public void Send() {  
    4.         System.out.println("this is mailsender!");  
    5.     }  
    6. }  
    [java] view plain copy
     
    1. public class SmsSender implements Sender {  
    2.   
    3.     @Override  
    4.     public void Send() {  
    5.         System.out.println("this is sms sender!");  
    6.     }  
    7. }  

    建造者模式实现

    1. public class Builder {  
    2.       
    3.     private List<Sender> list = new ArrayList<Sender>();  
    4.       
    5.     public void produceMailSender(int count){  
    6.         for(int i=0; i<count; i++){  
    7.             list.add(new MailSender());  
    8.         }  
    9.     }  
    10.       
    11.     public void produceSmsSender(int count){  
    12.         for(int i=0; i<count; i++){  
    13.             list.add(new SmsSender());  
    14.         }  
    15.     }  
    16. }  

    测试类

    1. public class Test {  
    2.   
    3.     public static void main(String[] args) {  
    4.         Builder builder = new Builder();  
    5.         builder.produceMailSender(10);  
    6.     }
    7. }

    7>原型模式

    public class Prototype implements Cloneable , Serializable{

     

    private static final long serialVersionUID = 6575573039264223590L;

     

    private int i;

    private Person p;

     

    //浅复制

    @Override

    public Object clone() throws CloneNotSupportedException {

    Prototype prototype = (Prototype) super.clone();

    return prototype;

    }

     

    //深复制

    public Object deepClone() throws CloneNotSupportedException, IOException, ClassNotFoundException {

    ByteArrayOutputStream bao = new ByteArrayOutputStream();

    ObjectOutputStream oo = new ObjectOutputStream(bao);

    oo.writeObject(this);

     

    ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());

    ObjectInputStream ois = new ObjectInputStream(bai);

    Object object = ois.readObject();

     

    return object;

    }

     

     

    @Override

    public String toString() {

    return "Prototype [i=" + i + ", p=" + p + "]";

    }

     

    public int getI() {

    return i;

    }

     

    public void setI(int i) {

    this.i = i;

    }

     

    public Person getP() {

    return p;

    }

     

    public void setP(Person p) {

    this.p = p;

    }

     

    }

    一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口,你可以任意定义实现类的方法名,如cloneA或者cloneB,因为此处的重点是super.clone()这句话,super.clone()调用的是Object的clone()方法,而在Object类中,clone()是native的。首先需要了解对象深、浅复制的概念:

    浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

    深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

  • 相关阅读:
    软链接
    yum
    vm
    tengine
    创智LIUNX
    作业11
    作业10
    作业9
    作业8
    作业7
  • 原文地址:https://www.cnblogs.com/-wyl/p/7156687.html
Copyright © 2020-2023  润新知