文档章节

JAVA架构师半小时学会常用设计模式

凯文加内特
 凯文加内特
发布于 03/01 09:07
字数 2696
阅读 19
收藏 10

以下为个人学习后的感悟,若有问题请大神们指出来~

目录

一、Proxy Pattern 代理模式(需要代理人)

二、Singleton Pattern 单例模式(不需要多次实例化某对象,节省资源消耗)

三、Strategy Pattern 策略模式(商场有多种优惠策略)

四、Template Pattern 模版模式(全国统考,保持试卷一致,修改变更)

五、Abstract Factory Pattern 抽象工厂模式(服务端连接不同数据库),含反射用法示例

一、Proxy Pattern 代理模式(需要代理人)
    概念:代理是代替另一个类(这里我称呼它为“被代理类”),它通常和代理的类拥有一样的接口,并且实现接口。

    个人理解:现在每天都会诞生无数的明星,如果你是某小公司的负责人,需要邀请明星来拍摄广告或者邀请做形象代言人,一般是没办法和明星直接面谈,那怎么办呢?明星的经纪人就出现了,有生意找经纪人谈,如果有什么问题可以委托经纪人和明星内部沟通交流。

      代码示例:

步骤一,定义共同的接口SubjectApi抽象类

abstract class SubjectApi {
    public abstract void Request();
}


步骤二,代理者Proxy类和被代理者RealSubject类都继承抽象类SubjectApi,并实现接口

//被代理者类

public class RealSubject extends SubjectApi {
    @Override
    public void Request() {
        System.out.println("真实的请求");
    }
}


//代理者类

public class Proxy extends SubjectApi {
    private RealSubject realSubject;         ----注意,这里用了关联的方式
    @Override
    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.Request();
    }
}


//访问者

public class DemoTest {
    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.Request();
    }
}


输出结果:

真实的请求

二、Singleton Pattern 单例模式(不需要多次实例化某对象,节省资源消耗)
       概念:单例模式,常用于封装之后,可以在生命周期范围内维持使用它。只需要创建一次,相当于懒实例化的效果。比如在构造函数中需要执行比如访问远程数据库的操作,操作可能会很耗时和耗资源。

     个人理解:比如在一定长的时间范围内,需要频繁调用某服务的接口,这时如果该服务只实例化一次,在频繁调用的时候就不需要每次都实例化一遍。

代码示例一(双重锁定示例):

步骤一,创建单例对象,对外仅提供访问实例化的对象方法GetInstance。判断是否已实例化,如果没有则new操作创建并实例化对象 ;已实例化则直接返回对象。

public class Singleton {
    private static Singleton instance;
    private static final Object syncRoot = new Object();

    private Singleton() {

    }

    public static Singleton GetInstance() {
        if (instance == null) {                        ----双重锁定,当对象已实例化时,其他线程访问时就不会再做加锁操作
            synchronized(Singleton.class){             ----当多线程访问时,加锁保证对象不会被实例化多次
                if (instance == null) {
                    instance = new Singleton();
                    System.out.println("实例化对象");
                }
            }
        }
        return instance;
    }
}


步骤二,访问者访问对象

public class Test {
    public static void main(String[] args) {
        Singleton s1 = Singleton.GetInstance();
        Singleton s2 = Singleton.GetInstance();
        if (s1 == s2) {
            System.out.println("两个对象是相同的实例");
        }
    }
}


代码示例二(饿汉式(静态常量)静态初始化示例):

public class SingletonInit {
    private static SingletonInit instance = new SingletonInit();
    private SingletonInit() {
    }

    public static SingletonInit GetInstance() {
        return instance;
    }
}


代码示例三 饿汉式(静态代码块):

public class Singleton {

    private static Singleton instance;

    static {
        instance = new Singleton();
    }

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}


三、Strategy Pattern 策略模式(商场有多种优惠策略)
       概念:策略被适用于在同一算法有不同的实现或不同的操作方式,运行的时候会动态选择。通常来说,公共的方法在抽象类中实现,提供给子类能实现不同的行为。客户端通常可以查看不同的策略并选择使用它。

      个人理解:比较明显的例子,就是商场买衣服,3月份打8折,4月份打7折,6月份买一送一的活动方案。代码示例:

步骤一,提供策略类,定义所有的策略方案有共同的接口提供。

abstract class Strategy {
    public abstract void AlgorithmInterface();
}


步骤二,统一继承策略类,依次实现策略A、策略B、策略C

public class ConcreteStrategyA extends Strategy {
    @Override
    public void AlgorithmInterface() {
        System.out.println("新款商品,不参与活动");
    }
}


public class ConcreteStrategyB extends Strategy {
    @Override
    public void AlgorithmInterface() {
        System.out.println("符合活动条件满300返200");
    }
}


public class ConcreteStrategyC extends Strategy {
    @Override
    public void AlgorithmInterface() {
        System.out.println("符合活动条件,打8折");
    }
}


步骤三,创建策略工厂,包含哪些策略方案

public class Context {
    private Strategy strategy;
    public Context(String type) {
        switch (type) {                                 ----可以优化的方式,不需要用switch-case,变更办法是使用反射技术
            case "正常收费":
                strategy = new ConcreteStrategyA();
                break;
            case "满300返200":
                strategy = new ConcreteStrategyB();
                break;
            case "打8折":
                strategy = new ConcreteStrategyC();
                break;
        }
    }

    public void ContextInterface() {
        strategy.AlgorithmInterface();
    }
}

步骤四,商场人员选择策略,不需要让商场人员知道这个策略是哪个方法实现的

public class Test {
    public static void main(String[] args) {
        Context context;
        context = new Context("正常收费");
        context.ContextInterface();

        context = new Context("打8折");
        context.ContextInterface();

        context = new Context("满300返200");
        context.ContextInterface();
    }
}


输出结果:

新款商品,不参与活动
符合活动条件,打8折
符合活动条件满300返200

四、Template Pattern 模版模式(全国统考,保持试卷一致,修改变更)
       概念:模版模式是实现一个抽象类并经常被用于提供一个蓝图或大纲。有时候,也被使用于实现系统的钩子,例如一个应用程序框架。(中文水平不好哈)

  个人理解:比如创建一份统一试卷,提供给班级每个学生测试,学生在上面填写答案即可。试卷修改的时候,可以一次性把所有试卷的内容都修改。代码示例:

步骤一,创建试卷,并提供填写答案的方法Answer1、Answer2、Answer3。

abstract class TestPaper {
    public void TestQuestion1(){
        System.out.println("题目1,杨过来过,郭敬也来过,来了几个人?");
        System.out.println("答案:" + Answer1());
    }

    public void TestQuestion2(){
        System.out.println("题目1,小强来过,小明也来过,来了几个人?");
        System.out.println("答案:" + Answer2());
    }

    public void TestQuestion3(){
        System.out.println("题目1,小强走了,小明还在,还有几个人?");
        System.out.println("答案:" + Answer3());
    }

    public abstract String Answer1();
    public abstract String Answer2();
    public abstract String Answer3();
}


步骤二,学生A、学生B填写试卷

public class TestPaperA extends TestPaper {
    @Override
    public String Answer1() {
        return "B";
    }

    @Override
    public String Answer2() {
        return "C";
    }

    @Override
    public String Answer3() {
        return "A";
    }
}
public class TestPaperB extends TestPaper {
    @Override
    public String Answer1() {
        return "A";
    }

    @Override
    public String Answer2() {
        return "B";
    }

    @Override
    public String Answer3() {
        return "C";
    }
}


步骤三,给学生分发试卷,查看学生填写试卷结果

public class Test {
    public static void main(String[] args) {
        System.out.println("学生甲的开始试卷答题:");
        TestPaper testPaperA = new TestPaperA();
        testPaperA.TestQuestion1();
        testPaperA.TestQuestion2();
        testPaperA.TestQuestion3();

        System.out.println("学生乙的开始试卷答题:");
        TestPaper testPaperB = new TestPaperB();
        testPaperB.TestQuestion1();
        testPaperB.TestQuestion2();
        testPaperB.TestQuestion3();
    }
}


输出结果:

学生甲的开始试卷答题:
题目1,杨过来过,郭敬也来过,来了几个人?
答案:B
题目1,小强来过,小明也来过,来了几个人?
答案:C
题目1,小强走了,小明还在,还有几个人?
答案:A
学生乙的开始试卷答题:
题目1,杨过来过,郭敬也来过,来了几个人?
答案:A
题目1,小强来过,小明也来过,来了几个人?
答案:B
题目1,小强走了,小明还在,还有几个人?
答案:C

五、Abstract Factory Pattern 抽象工厂模式(服务端连接不同数据库),含反射用法示例
       概念:不同于单例模式。这个模式适用于运行时需要选择模式,并且该模式下包含不同的兼容类需要实例化处理。该模式在JAVA API中使用。

       个人理解:比如当需求变更,原先服务端访问的是ORACLE数据库,现在要替换成MYSQL、SQLSERVER等,会因为SQL语法做出重大和繁琐的改造工作。

代码示例:

步骤一,定义访问数据库表的统一接口方法(查询、插入)。

public interface IUser {
    void InsertUser(User user);

    User GetUser(Integer id);
}


步骤二,在SQL SERVER方式中,分别实现对User表和Department表的操作

public class SqlserverUser implements IUser {
    @Override
    public void InsertUser(User user) {
        System.out.println("在SQL SERVER中给User表新增一条记录");
    }

    @Override
    public User GetUser(Integer id){
        System.out.println("在SQL SERVER中根据ID得到User表一条记录");
        return null;
    }
}
public class SqlserverDepartment implements IDepartment {
    @Override
    public void InsertDeptment(Department department) {
        System.out.println("在SQL SERVER中给Deptment表新增一条记录");
    }

    @Override
    public Department GetDepartment(Integer id) {
        System.out.println("在SQL SERVER中根据ID得到Deptment表一条记录");
        return null;
    }
}


步骤三,在Access数据库方式中,分别实现对User表和Department表的操作

public class AccessUser implements IUser {
    @Override
    public void InsertUser(User user) {
        System.out.println("在Access中给User表新增一条记录");
    }

    @Override
    public User GetUser(Integer id) {
        System.out.println("在Access中根据ID得到User表一条记录");
        return null;
    }
}
public class AccessDepartment implements IDepartment {
    @Override
    public void InsertDeptment(Department department) {
        System.out.println("在Access中给Department表新增一条记录");
    }

    @Override
    public Department GetDepartment(Integer id) {
        System.out.println("在Access中根据ID得到Department表一条记录");
        return null;
    }
}


步骤四,创建简单的工厂模式类,其中注释部分大家可以看下,传统工厂模式的写法

这里采用反射的实现方法Class.forName(className).newInstance()

其中,className是包+类名称,newInstance()为实例化类

public class DataAccess {
    private static final String db = "Sqlserver";
    private static final String AssemblyName = "abstractfactory";

    public static IUser CreateUser() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//        IUser result = null;
//        switch (db) {
//            case "SqlServer":
//                result = new SqlserverUser();
//                break;
//            case "Access":
//                result = new AccessUser();
//                break;
//        }
//        return result;
        String className = AssemblyName + "." + db + "User";
        return (IUser)Class.forName(className).newInstance();
    }

    public static IDepartment CreateDepartment() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//        IDepartment result = null;
//        switch (db) {
//            case "SqlServer":
//                result = new SqlserverDepartment();
//                break;
//            case "Access":
//                result = new AccessDepartment();
//                break;
//        }
//        return result;
        String className = AssemblyName + "." + db + "Department";
        return (IDepartment)Class.forName(className).newInstance();
    }
}


步骤五,选择数据库进行数据访问

public class FactoryTest {
    public static void main(String[] args) {
       //一般工厂模式
        User user = new User();
//        IFactory factory = new SqlServerFactory();                   ----选择数据库方式
        IFactory factory = new AccessFactory();
        IUser iUser = factory.CreateUser();
        iUser.InsertUser(user);
        iUser.GetUser(1);

        Department department = new Department();
        IDepartment iDepartment = factory.CreateDepartment();
        iDepartment.InsertDeptment(department);
        iDepartment.GetDepartment(1);

        //抽象工厂模式
        User user1 = new User();
        IUser iUser1 = null;
        try {
            iUser1 = DataAccess.CreateUser();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        iUser1.InsertUser(user1);
        iUser1.GetUser(1);

        Department department1 = new Department();
        IDepartment iDepartment1 = null;
        try {
            iDepartment1 = DataAccess.CreateDepartment();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        iDepartment1.InsertDeptment(department1);
        iDepartment1.GetDepartment(1);

    }
}


输出结果:

在Access中给User表新增一条记录
在Access中根据ID得到User表一条记录
在Access中给Department表新增一条记录
在Access中根据ID得到Department表一条记录
在SQL SERVER中给User表新增一条记录
在SQL SERVER中根据ID得到User表一条记录
在SQL SERVER中给Deptment表新增一条记录
在SQL SERVER中根据ID得到Deptment表一条记录


 

本文转载自:https://blog.csdn.net/feixiang3447/article/details/81671448 

凯文加内特
粉丝 341
博文 701
码字总数 110786
作品 0
青岛
后端工程师
私信 提问
Java程序员2019学习方向,高并发,分布式,Redis,微服务

JAVA架构师内功心法 做任何事之前,需要先打好基础。想入行Java,就必须掌握JavaSE基础;其次是各种设计模式都要会,常用的就二十几种,像单例模式、工厂模式等等,一定要运用得滚瓜烂熟;然...

别打我会飞
02/13
136
0
设计模式 2014-12-19

book: 阎宏《JAVA与模式》 架构设计栏目 http://blog.csdn.net/enterprise/column.html 概要: http://bbs.csdn.net/forums/Embeddeddriver 23种设计模式分别是: 1.单例模式 2.工厂方法模式...

jayronwang
2014/12/19
293
0
23种设计模式(1):单例模式

定义:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 类型:创建类模式 类图: 类图知识点: 1.类图分为三部分,依次是类名、属性、方法 2.以<<开头和以>>结尾的为注释...

LCZ777
2014/07/05
248
0
Java单例设计模式的理解与常规实现方式

1:Java中单例模式是一种常见的设计模式,单例模式有以下特点:   单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 2:java中单例模式的写法也有很多种,我在这...

动力节点
01/02
0
0
设计模式15——Template Method设计模式

Template Method模板方法设计模式定义一个操作中算法的骨架,将具体步骤的执行延迟到子类中实现。Java中的抽象类就是使用了模板方法设计模式。模板方法设计模式结构如下: 以文档处理为例,T...

小米米儿小
2014/01/24
214
0

没有更多内容

加载失败,请刷新页面

加载更多

移动深度学习:人工智能的深水区

人工智能技术经历6年的快速发展,重新定义了很多行业的用户体验,而这仅是开始。 随着5G商用大规模落地,以及智能手机硬件性能越来越强、AIoT设备的快速普及,基于云-边缘-端算法和算力结构的...

博文视点Bv
20分钟前
2
0
vim 分屏 操作

$vim -On file file2 #大写O垂直分屏打开文件 $vim -on file file2 #小写水平打开 # n 表示分屏数,直接n等于文件个数 如果n小于文件,按顺序打开前面的n个,如果大于,打开空编辑页面 分屏快...

突突突酱
23分钟前
2
0
MySQL/Mariadb设置中文字符集(linux)

编辑/etc/my.cnf,添加以下设置 [mysql]default-character-set=utf8[mysqld]character_set_server=utf8[mysqld.safe]default-character-set=utf8[client]default-chara...

编程老陆
26分钟前
3
0
关于linux常用的挂载命令

挂载:就把一块磁盘(可以是光盘,U盘)绑定到一个空目录下面 一般情况下会挂载到mnt目录下面 挂载光盘(把光盘挂载到/mnt/cdrom这个目录中) mount -t iso9660 /dev/cdrom /mnt/cdrom 退出当前目录...

chenhongjiang
27分钟前
3
0
如何分享brain内容外部共享?几个需要知道的TheBrain问答

TheBrain(点击下载)是一款与众不同的思维导图软件,其所有信息通过一个又一个的节点进行联系,最终形成一个杂而不乱的网状结构。从头开始设计,让您捕获您的想法和信息在一个网络的联想,匹...

mnrssj
27分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部