TCP实现客户端向服务器发送对象
封装User类
其中implements java.io.Serializable
实现这个接口是为了让User
类的对象能够被序列化。序列化是将对象转换为字节流的过程,这样对象就可以在网络上传输或者保存到文件中。
//序列化
public class User implements java.io.Serializable{
private String userName;
private String passWord;
public User() {
super();
}
public User(String userName, String passWord) {
super();
setUserName(userName);
setPassWord(passWord);
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", passWord='" + passWord + '\'' +
'}';
}
}
服务端
public class ServerUserTest {
public static void main(String[] args) {
//1.创建一个ServerSocket类型的对象并提供端口
try {
ServerSocket ss = new ServerSocket(9898);
//2.等待客户端连接请求,调用accept方法
System.out.println("等待客户端的连接请求......");
Socket s = ss.accept();
System.out.println("客户端连接成功!!!");
//3.使用输入输出流进行通信
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
Object obj = ois.readObject();
System.out.println("服务器收到数据为:" + obj);
//4.关闭Socket
s.close();
ss.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
客户端
public class ClientUserTest {
public static void main(String[] args) {
try {
//1.创建Socket类型的对象并提供服务器额IP地址和端口号;
//InetAddress.getLocalHost()当前本地的地址
Socket s = new Socket(InetAddress.getLocalHost(),9898);
//2.使用输入输出流
//准备一个User类型的对象并初始化
User tu = new User("amin","123456");
//使用输出流将User类型的对象整体发出去
ObjectOutputStream oos= new ObjectOutputStream(s.getOutputStream());
oos.writeObject(tu);
System.out.println("客户端发送对象成功");
//3.关闭Socket
oos.close();
s.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
软件开发的流程
需求分析文档 ==>> 概要设计文档 大概设计需要多少模块和多少功能 ==>> 详细设计文档 我写成个模块大概需要多少个类 类大概长什么样子 类之间的关系 ==>> 编码和测试 ==>> 安装和调试 ==>>维护和升级
常用的设计原则
开闭原则
开闭原则:对扩展开放,对修改关闭。
一旦代码写完测试后无问题就不要再修改了,需要新增元素时可以继承扩展。
提高了代码的扩展性和维护性。
里氏代换原则
任何父类可以出现的地方,子类一定可以出现。子类 is a 父类。在以后的开发中多使用继承和多态的理念。
依赖倒转原则
尽量依赖于抽象类和接口,而不是具体实现类.
尽量在以后的开发中多使用抽象类和接口,对子类具有强制性和规范性。
接口隔离原则
尽量依赖于小接口而不是大接口,避免接口污染。
可以降低耦合性
耦合主要指一个模块与其他模块之间的关联度
迪米特法则
也是最少知道原则
低耦合,高内聚
高内聚就是指将一个实体应该拥有的功能尽量聚集在该实体内部。
一个实体应尽量少与其他实体之间发生相互作用,使系统模块相对独立。
合成复用原则
尽量多使用合成的方式,而不是继承的方式。
常用的设计模式和概念
设计模式是一套被反复使用、多数人知晓、经过分类编目的、多年编程代码设计经验的总结。
设计模式就是一种用于固定场合的固定套路。
单列设计模式、模板设计模式、工厂方法模式、抽象工厂模式。
普通工厂方法模式
参考类图编写程序
编写接口
public interface Sender {
//自定义描述发送行为的抽象方法
public abstract void send();
}
接口类的实现
public class MaliSender implements Sender{
@Override
public void send() {
System.out.println("正在发送邮件......");
}
}
public class SmsSender implements Sender{
@Override
public void send() {
System.out.println("正在发送短信......");
}
}
构造对象的行为(工厂类,生产下面mail和sms两个类 )
public class SenderFactory {
//自定义成员方法描述构造对象的行为
public Sender produce(String type){
if ("mail".equals(type)){
return new MaliSender();
}
if ("sms".equals(type)){
return new SmsSender();
}
return null;
}
}
public class SenderFactoryTest {
public static void main(String[] args) {
//声明SenderFactory类型的引用指向该类型的对象
SenderFactory sf = new SenderFactory();
//调用成员方法实现对象的创建
Sender s = sf.produce("mail");
s.send();
//输出为: 正在发送邮件......
}
}
以上就是普通工厂模式的编写案例。工厂模式虽然代码复杂,但是提高了代码的拓展性和可维护性。仅限于使用大量的对象时更为便捷。
抽象工厂方法模式
常用的查找算法
线性/顺序查找算法的实现
使用目标元素与样本数列中的第一个元素起依次比较;
若找到与目标元素相等的元素,则表示查找成功;
若目标元素与所有样本元素比较完毕也不相等,则表示查找失败;
public class FindTest {
//自定义成员方法实现线性查找算法
//从参数指定的数组中查找参数指定元素所在的下标并返回出来
public static int find(int[] arr,int num){
for (int i = 0; i < arr.length; i++) {
if (num == arr[i]){
return i;
}
}
return -1;//表示查找失败
}
public static void main(String[] args) {
int[]brr = {10,20,30,40,50};
int num = 20;
int res = FindTest.find(brr,num);
if (-1 == res){
System.out.println(num + "查找失败!");
}else {
System.out.println(num + "在数组中的下标时:" + res);
}
}
}
二分/折半查找算法
顺序虽然简单,但是效率较低,此方法类似于猜数字,1 ~ 100之间的数字,每次猜出数字都会说出数字大了还是小了,依次缩小范围。
假定样本数列中的元素是从小到大依次排序的;使用目标元素与样本数列中的中间元素进行比较;
若目标元素与中间元素相等,则表示查找成功;
若目标元素小于中间元素,则去中间元素的左边进行查找;
若目标元素大于中间元素,则去中间元素的右边进行查找;
直到目标元素与所有该比较的元素比较完毕后也不相等,则表示查找失败;
先获取中间元素进行对比,当剩余两个元素时下标相加除以2在获取整数来选择两个元素与谁做对比。
//自定义成员方法实现二分查找算法
public static int findBinary(int[]arr,int left,int right,int num){
//样本数列中至少有一个元素时才有查找的必要
if (left <= right){
//1.计算中间运算的下标,找到中间元素
int p = (left + right)/2;
//2.使用目标元素与中间元素比较是否相等,若相等则直接返回下标
if (num == arr[p]){
return p;
}
//3.若目标元素小于中间元素,则去中间元素的左边查找,使用递归的思想
if (num < arr[p]){
return findBinary(arr,left,p-1,num);
}
//4.若目标元素大于中间元素,则去中间元素的右边查找,使用递归的思想
return findBinary(arr,p+1,right,num);
}
return -1;
}
public static void main(String[] args) {
int[]brr = {10,20,30,40,50};
int num = 20;
int res = FindTest.findBinary(brr,0,4,num);
if (-1 == res){
System.out.println(num + "查找失败!");
}else {
System.out.println(num + "在数组中的下标时:" + res);
}
}
评论区