设计思想-第一篇-初出茅庐

Posted 是摩卡不是抹茶呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计思想-第一篇-初出茅庐相关的知识,希望对你有一定的参考价值。

MoCha 设计思想 - 第一篇

文章内容是初学Java时,记录的内容,现在回头看感觉很有意思。

1)、设计思想之限制接口调用的参数范围

经验:
  如果我们想要将一个方法的参数入口范围变得局限点
  可以将该方法的参数类型设置得小点,然后在该方法的内部调用某个功能相似的方法
  这个功能相似方法的参数入口范围是比我们设定的方法参数范围大

扩展思维:
  可以将我们设定的方法设置为public
  将内部调用的方法设置为private
  这样一来,外部类就只能通过调用我们设定的方法来对参数赋值
  更大范围的方法别人是访问不到的

2)、设计思想之利用Properties类读取配置文件

/**
 * 运用Properties属性集合和IO流(InputStream 、Reader都可以)
 * 设计当某个模块的执行达到一定规模时,转向执行另外一个操作
 */
Properties prop = new Properties();
Reader reader = new FileReader("Count.txt");

prop.load(reader); // 既可以接收Readr , 也可以接收InputStream

String value = prop.getProperty("count");
int number = Integer.parseInt(value);

if(number > 5){
	// 输出提示
} else{
	// 否则执行该模块语句
}

3)、设计思想之关于多线程中线程安全问题

设置和获取线程的资源应该是同一个资源(设计思想)

那么问题来了,怎么实现呢?
	实现方案:
		在外界把这个资源创建出来,通过构造方法的参数将该资源传递给其他类
		然后将这个资源作为锁(通常都是将资源作为构造参数传递给其他线程对象)

4)、设计思想之生产者与消费者问题

(重点)
锁对象等待后,"立即释放锁" . 等到唤醒时,从这个这地方苏醒

(重点)
锁对象唤醒并不表示可以立即执行,必须得抢CPU的时间片
					
boolean flag; // 默认值为false

/** 生产者 */
public synchronized void set(String name, int age){
	// 如果有数据,就等待
	if(this.flag){
		try {
			this.wait();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	} 
	// 生产数据
	this.name = name;
	this.age = age;
	
	this.flag = true; // 生产完后,就有数据了,所以为true
	this.notify(); // 唤醒消费者
	
}

/** 消费者 */
public synchronized void get(){
	if(!this.flag){
		try {
			this.wait();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	/*-- 这是消费行为 -*/
	System.out.println(this.name + " --- " + this.age);
	
	this.flag = false; // 消费完后,就没有数据,所以为false
	this.notify();
}

5)、设计思想之关于文件复制和删除问题

文件的复制和删除多与
	增强for循环、File[] fileArray = file.listFiles();
一起使用

6)、设计思想之在GUI中,如何善用API?(查找我们不了解的方法或类)

例如:
(1)获取颜色 , 可以找Color普通类 -> Color.BLACK

(2)想要在程序中使用dos命令 , 可以找Runtime普通类 
	--> Runtime rt = Runtime.getRuntime()
				rt.exec(String command)	
				   
(3)想要获取工具包 , 可以找Toolkit
	Toolkit tk = Toolkit.getDefaultToolkit(); // 获取默认工具包 , 返回值为Toolkit类型
	// 该方法返回一个Dimension对象,该对象封装了单个组件的宽和高		
	Dimension d = tk.getScreenSize(); // 获取屏幕的大小
											
  /**
   * 根据路径获取图片对象 , 该方法返回值类型为Image
   * 注意!!!图片的路径是要全路径
   */
	Image i = tk.getImage("src\\\\source\\\\休闲桌面.jpg");
	jf.setIconImage(i);
			
(4)UIManger

7)、设计思想之如何将JFrame窗体的坐标位置居中?

/**
 * 将JFrame窗体的坐标位置居中
 *
 * 如何将JFrame窗体的坐标位置居中呢?
 * 思路:
 * 1:获取JFrame窗体的宽和高
 * 2:获取屏幕的宽和高
 * 3:将(屏幕的宽 - JFrame窗体的宽) / 2
 * 	  (屏幕的高 - JFrame窗体的高) / 2
 * 	 作为JFrame窗体的新坐标
 *
 * @param jf	JFrame窗体对象
 */
public static void setLocation(JFrame jf){
	// 要想获取屏幕的宽和高,就得借助Toolkit工具包
	Toolkit tk = Toolkit.getDefaultToolkit();
	
	// 获取屏幕的宽和高 , 该方法返回一个Dimension对象,该对象封装了单个组件的宽和高
	Dimension d = tk.getScreenSize();
	double screenWidth = d.getWidth();//该方法返回的是double
	double screenHeight = d.getHeight();
	
	/** 获取JFrame窗体的宽和高 */
	int jfWidth = jf.getWidth();
	int jfHeight = jf.getHeight();
	
	/** JFrame窗体的新坐标 */
	int x = (int)(screenWidth - jfWidth)/2;
	int y = (int)(screenHeight - jfHeight)/2;
	
	jf.setLocation(x, y);
}

8)、设计思想之IO版用户登录注册

关键是如何设定规则将信息存放到用户表,就怎么从用户表读取信息

/**
* 为用户进行注册
* 我们需要定义一个规则
* 用户的信息是由以下格式组成:
* userName=passWord
* @param user
*/
public static void register(User user){
	BufferedWriter bw = null;
	// 要注意对user表进行信息追加
	try {
		bw = new BufferedWriter(new FileWriter(file , true));
		bw.write(user.getUserName() + "=" +user.getPassWord());
		bw.newLine();
		bw.flush();
	} catch (IOException e) {
		e.printStackTrace();
	}finally {
		if(bw!=null){
			try {
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
}

/**
* 用户登录功能
* @param name		用户名
* @param passWord	用户密码
*/
public static boolean login(String name , String passWord){
	boolean flag = false;
	BufferedReader br = null;
	try {
		br = new BufferedReader(new FileReader(file));
		String line = null;
		while((line = br.readLine())!= null){
			String[] messageS = line.split("=");
			if(messageS[0].equals(name) && messageS[1].equals(passWord)){
				flag = true;
				break;
			}
		}
		// 用户信息匹配,进行登录
	} catch (IOException e) {
		e.printStackTrace();
	} finally {
		if(br!=null){
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	return flag; // 信息不匹配,登录失败
}

9)、设计思想之集合版用户登录注册

关键是在于一开始就静态加载ArrayList<User>, 还有遍历ArrayList的形式

/** 为了让集合的对象在注册和登录时统一,于是我们将集合定义为成员变量 */
/** 为了不让外人看见,我们将存放用户信息的集合设置为private */
/** 为了能够让对象共享存放的用户信息,我们将集合设置为static */
private static ArrayList<User> list = new ArrayList<User>();

// 判断用户登录时,用户的信息是否匹配,如果不匹配就返回false
@Override
public boolean login(String name, String passWord) {
	for (User user : list) {
		if (user.getUserName().equals(name) 
				&& user.getPassWord().equals(passWord)) {
			return true;
		}
	}
	return false;
}

// 将注册的用户信息存储到集合中
@Override 
public void register(User user) {
	list.add(user);
}	

10)、设计思想之关于GUI设计

(1)
  注册控件 
  设置鼠标样式使用代码: 
  lblRegister.setCursor(new Cursor(Cursor.HAND_CURSOR)); // 可以使鼠标变成抓手

(2)"<html><u>进行注册</u><html>"可以使标签文字有下划线

(3)如何将子窗体关闭? - 子窗体要在桌面面板上, 菜单栏上添加的是MenuItem , 不是Menu
	子窗体.setClosable();

(4)如何使子窗体只有一个?(以下代码在主界面中)
	private JInternalFrame inFrame = null;
	(在子窗体的监听事件里)
	if(inFrame!=null){	//此时说明有子窗体
		inFrame.dispose();
	}
	JInternalOper f1 = new JInternalOper();
	f1.setVisable(true);
	desktopPane.add(f1);
	inFrame = f1;

11)、设计思想之如果一个类没有构造方法

如果一个类没有构造方法, 那么有以下情况:
	(1)成员都是静态的,(MathArraysCollections)
	(2)单例设计模式,(Runtime)
	(3)类中有静态方法返回该类对象(InetAddress)
      class Demo{
        private Demo(){}
        public static Demo getXxx(){
          return new Demo();
        }
      }

12)、设计思想之在IO流中如何使文本反转?

分析:
(1)创建输入输出流
(2)创建集合对象
(3)将读取到的数据存入到集合中
(4)倒着遍历集合
(5)关流

13)、设计思想之在ArrayList<Integer>中添加其他数据类型的数据

/*
如果想要在ArrayList<Integer>中添加其他数据类型的数据,可以做到吗?如何实现?
	通过反射原理来实现
* 使用反射原理
* (1)获得ArrayList的Class对象 - 这里已经提供了对象,所以可以直接通过对象调用getClass()
* (2)通过Class对象去获取add方法并使用
* 
* 分析为什么可以通过反射原理来实现越过泛型进行添加元素
* 因为:泛型的作用主要体现在编译期间,可以有效的避免错误数据类型的添加
* 实际上,集合的add(E e)方法的参数是E类型的,也就是说在代码执行过程中
* 方法参数类型是没有什么影响的,可以放其他类型数据,String,甚至是某个类的对象
* 
* 反射所做的就是从ArrayList集合对象的Class对象入手
* 获取集合的add(E e)方法来直接使用
* 效果相当于去掉泛型
*/
代码示例:
	ArrayList<Integer> list = new ArrayList<Integer>();
	
	Class c = list.getClass();
	Method m = c.getDeclaredMethod("add", Object.class);
	m.invoke(list , "hello");

	Student stu = new Student();	
	m.invoke(list , stu);
	
	System.out.println(list);

// 输出结果:
	[hello, Student [name = null, age = 0, id = null]]

14)、设计思想之运用反射原理实现给任意对象的任意字段设置值

/**
 * 实现给任意对象的任意字段设置值
 * @param obj	含有该字段的对象
 * @param name	要赋值的字段名称
 * @param value	要给字段赋的值
 * @throws Exception 
 */
public static void setProperties(Object obj, String name , Object value) throws Exception{
	// 获取Class对象
	Class c = obj.getClass();
	
	// 通过Class对象获取指定字段,因为获取到的字段有可能存在访问限制,得采取暴力访问
	Field f = c.getDeclaredField(name);
	f.setAccessible(true);
	f.set(obj, value);
}

15)、设计思想之如何优雅的读取配置文件?

// 如何读取配置文件?
		InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("properties.txt");
		Properties prop = new Properties();
		prop.load(is);
		
		String driverClass = prop.getProperty("driverClass");
		String url = prop.getProperty("url");
		String user = prop.getProperty("user");
		String password = prop.getProperty("password");	
		
// 配置文件在反射中的应用:
/**
* 使用反射运行配置文件内容
* 1:创建Properties属性集
* 2:将配置文件通过load()方法加载到属性集里
* 3:从属性集中获取数据
*/
Properties prop = new Properties();
FileReader fr = new FileReader("class.txt");
prop.load(fr);

// 通过属性集的键值获得对应的值
String className = prop.getProperty("className");
String MethodName = prop.getProperty("MethodName");

// 要注意配置文件里的类名路径
Class c = Class.forName(className);
Constructor con = c.getDeclaredConstructor();
con.setAccessible(true);
Object obj = con.newInstance();

Method m = c.getDeclaredMethod(MethodName);
m.setAccessible(true);
m.invoke(obj);

16)、设计思想之如何将一个客户端传来的信息发送给其他客户端

// 为了能够将客户端传送过来的信息发送给其他客户端,我们先将各个客户端存储到集合中
ArrayList<Client> clients = new ArrayList<Client>();

s = ss.accept();
Client client = new Client(s);
clients.add(client); // 将客户端添加到集合中
new Thread(client).start();

定义一个内部类实现Runnable接口
private class Client implements Runnable{...}

17)、设计思想之如何更快的进行文件复制?

1)复制文件:
代码举例:(直接一条语句搞定)
  Files.copy(Paths.get("a.txt"), new FileOutputStream("g.txt"));2)把集合数据写到文件
代码举例:
  ArrayList<String> list = new ArrayList<String>();
  list.add("杨泽锋");
  list.add("小树林");
  list.add("肥威");

  Files.write(Paths.get("g.txt"), list, Charset.forName("GBK"));

18)、设计思想之工具类的编写规则

(1) 如果工具类中有静态方法,那么就将构造器用private或者是使用abstract来修饰
	强制调用者,直接使用类名来调用工具方法(Arrays,Collections)
	
(2) 如果工具类中没有静态方法,那么就将工具类设计为单例模式

19)、设计思想之判断一个文件是否符合规定的某种类型

上传类型约束:{
// =====方式1:=====

private static final String ALLOWED_IMAGE_TYPE = "jpg;png;gif";

//在正式处理上传控件前,先判断文件是否符合我们想要的类型
String[] types = ALLOWED_IMAGE_TYPE.split(";");  // 因为数组不能直接判断一个元素是否包含在里面
boolean isType = Arrays.asList(types).contains(FilenameUtils.getExtension(FilenameUtils.getName(item.getName())));
// 我们先将数组转化为List集合,然后通过集合中的contains()方法来判断

if(!isType){
	req.setAttribute("errorMes", "Coder,您还没有正确选择文件喔");
	req.以上是关于设计思想-第一篇-初出茅庐的主要内容,如果未能解决你的问题,请参考以下文章

设计思想-第一篇-初出茅庐

云原生时代,你应该了解的Service Mesh

基于python的接口测试学习笔记一(初出茅庐)

java设计模式-设计原则-创建型模式-场景理解-第一篇

设计模式第一篇:概述耦合UML七大原则,详细分析总结(基于Java)

23种设计模式Java版第一篇