• 设计模式学习


    现在是在电信部门实习,每天空闲时间较多,所以就复习了一下设计模式。

    1. 工厂方法模式

    工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

    2. 抽象工厂模式

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这样一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。

    其实这个模式的好处就是,如果你现在想增加一个功能:发及时信息,则只需做一个实现类,实现Sender接口,同时做一个工厂类,实现Provider接口,就OK了,无需去改动现成的代码。这样做,拓展性较好!

    3. 单例模式

    网上有关单例模式的例子很多,这里采用多线程的单例模式。

    优点:

      ①某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。

      ②省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

      ③有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

    /**
     * 多线程的单例模式,使用双重校验机制
    * 使用多线程的单例模式的原因是:在多线程环境下,创建类的实例会出现问题,必须要对创建类的函数加上synchronized关键字,以防止实例化两个或者以上的实例。
    */ public class DoubleCheckMode { private volatile static DoubleCheckMode sDoubleCheckMode ; public DoubleCheckMode() { System.out.println(" created " + getClass().getSimpleName()); } public static DoubleCheckMode getInstance() { if (sDoubleCheckMode == null) synchronized (DoubleCheckMode.class) { if (sDoubleCheckMode == null) { sDoubleCheckMode = new DoubleCheckMode(); } } return sDoubleCheckMode; } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread() { @Override public void run() { super.run(); System.out.println("thread" + getId()); DoubleCheckMode.getInstance(); } }.start(); } } }

    或者

                使用静态内部实现的单例是懒加载的且线程安全。
                从网上资料得出如下结论:加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。
    public class Singleton {
    
        /* 私有构造方法,防止被实例化 */
        private Singleton() {
        }
    
        /* 此处使用一个内部类来维护单例 */
        private static class SingletonFactory {
            private static final Singleton instance = new Singleton();
        }
    
        /* 获取实例 */
        public static Singleton getInstance() {
            return SingletonFactory.instance;
        }
    
        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
        public Object readResolve() {
            return getInstance();
        }
    }

    或者

    public class SingletonTest {
    
        private static SingletonTest instance = null;
    
        private SingletonTest() {
        }
    
        private static synchronized void syncInit() {
            if (instance == null) {
                instance = new SingletonTest();
            }
        }
    
        public static SingletonTest getInstance() {
            if (instance == null) {
                syncInit();
            }
            return instance;
        }
    }

    4. 建造者模式

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

    public class Builder {
        
        private List<Sender> list = new ArrayList<Sender>();
        
        public void produceMailSender(int count){
            for(int i=0; i<count; i++){
                list.add(new MailSender());
            }
        }
        
        public void produceSmsSender(int count){
            for(int i=0; i<count; i++){
                list.add(new SmsSender());
            }
        }
        public static void main(String[] args) {
            Builder builder = new Builder();
            builder.produceMailSender(10);
        }
    }

    从这点看出,建造者模式将很多功能集成到一个类里,这个类可以创造出比较复杂的东西。所以与工程模式的区别就是:工厂模式关注的是创建单个产品,而建造者模式则关注创建符合对象,多个部分。因此,是选择工厂模式还是建造者模式,依实际情况而定。

    5. 原型模式

    原型模式就是讲一个对象作为原型,使用clone()方法来创建新的实例。

    public class Prototype implements Cloneable{
    
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        protected Object clone()   {
            try {
                return super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }finally {
                return null;
            }
        }
    
        public static void main ( String[] args){
            Prototype pro = new Prototype();
            Prototype pro1 = (Prototype)pro.clone();
        }
    }

     6.  适配器模式

    适配器模式的作用就是在原来的类上提供新功能。主要可分为3种:

      类适配:创建新类,继承源类,并实现新接口,例如 

    class  adapter extends oldClass  implements newFunc{}

      对象适配:创建新类持源类的实例,并实现新接口,例如 

    class adapter implements newFunc { private oldClass oldInstance ;}

      接口适配:创建新的抽象类实现旧接口方法。例如 

    abstract class adapter implements oldClassFunc { void newFunc();}

    7. 装饰模式

     给一类对象增加新的功能,装饰方法与具体的内部逻辑无关。例如:

    interface Source{ void method();}
    public class Decorator implements Source{
    
        private Source source ;
        public void decotate1(){
            System.out.println("decorate");
        }
        @Override
        public void method() {
    //内部逻辑 decotate1(); source.method(); } }

    8. 代理模式

    客户端通过代理类访问,代理类实现具体的实现细节,客户只需要使用代理类即可实现操作。

    这种模式可以对旧功能进行代理,用一个代理类调用原有的方法,且对产生的结果进行控制。

    interface Source{ void method();}
    
    class OldClass implements Source{
        @Override
        public void method() {
        }
    }
    
    class Proxy implements Source{
        private Source source = new OldClass();
    
        void doSomething(){}
        @Override
        public void method() {
            new Class1().Func1();
            source.method();
            new Class2().Func2();
            doSomething();
        }
    }

    9. 外观模式

    为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。这句话是百度百科的解释,有点难懂,但是没事,看下面的例子,我们在启动停止所有子系统的时候,为它们设计一个外观类,这样就可以实现统一的接口,这样即使有新增的子系统subSystem4,也可以在不修改客户端代码的情况下轻松完成。

    public class Facade {
        private subSystem1 subSystem1 = new subSystem1();
        private subSystem2 subSystem2 = new subSystem2();
        private subSystem3 subSystem3 = new subSystem3();
        
        public void startSystem(){
            subSystem1.start();
            subSystem2.start();
            subSystem3.start();
        }
        
        public void stopSystem(){
            subSystem1.stop();
            subSystem2.stop();
            subSystem3.stop();
        }
    }

    10. 桥接模式

    11. 组合模式

     组合模式是为了表示那些层次结构,同时部分和整体也可能是一样的结构,常见的如文件夹或者树。举例:

    abstract class component{}
    
    class File extends  component{ String filename;}
    
    class Folder extends  component{
        component[] files ;  //既可以放文件File类,也可以放文件夹Folder类。Folder类下又有子文件或子文件夹。
        String foldername ;
        public Folder(component[] source){ files = source ;}
        
        public void scan(){
            for ( component f:files){
                if ( f instanceof File){
                    System.out.println("File "+((File) f).filename);
                }else if(f instanceof Folder){
                    Folder e = (Folder)f ;
                    System.out.println("Folder "+e.foldername);
                    e.scan();
                }
            }
        }
        
    }

    12. 享元模式

     使用共享对象的方法,用来尽可能减少内存使用量以及分享资讯。通常使用工厂类辅助,例子中使用一个HashMap类进行辅助判断,数据池中是否已经有了目标实例,如果有,则直接返回,不需要多次创建重复实例。

    abstract class flywei{ }
    
    public class Flyweight extends flywei{
        Object obj ;
        public Flyweight(Object obj){
            this.obj = obj;
        }
    }
    
    class  FlyweightFactory{
        private HashMap<Object,Flyweight> data;
    
        public FlyweightFactory(){ data = new HashMap<>();}
    
        public Flyweight getFlyweight(Object object){
            if ( data.containsKey(object)){
                return data.get(object);
            }else {
                Flyweight flyweight = new Flyweight(object);
                data.put(object,flyweight);
                return flyweight;
            }
        }
    }

  • 相关阅读:
    redis主从之过期key判断
    PHP之回调、匿名函数
    调试printf,fprintf (转)
    第一天,来报道
    hdu 4464 browsing history
    腾讯编程马拉松2012第一题
    今天面试悲剧了,看来面试前看考题是很关键的.
    JQuery访问WebService(可访问Java[Xfire])
    自己留备份,不解释.
    MYSQL UNION AND UNION ALL 的区别!
  • 原文地址:https://www.cnblogs.com/20158424-hxlz/p/10237435.html
Copyright © 2020-2023  润新知