1、密码硬编码
不安全。
将密码以明文的形式直接写到代码中,就是密码硬编码。
2、什么是卫语句
卫语句(guard clauses)是一种改善嵌套代码的优化代码。将经过多级嵌套的代码使用卫语句优化之后,代码嵌套层数可以降低,因此改使用卫语句能降低代码的复杂程度。卫语句是通过对原条件进行逻辑分析,将某些要害(guard)条件优先作判断,从而简化程序的流程走向,因此称为卫语句。
————————————————
版权声明:本文为CSDN博主「暗诺星刻」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangpaiblog/article/details/114909737
卫语句往往用于对 if 条件嵌套代码的优化。
3、分解条件表达式,提炼独立函数
1)、分解条件表达式
修改点:你有一个复杂的条件语句(就是if else语句)
做法:将条件表达式的三个部分分别提炼出独立函数
即
这三个部分都提炼成函数就好了。
2)合并条件表达式
修改点:你有一系列测试,都得到相同结果
做法:将这些测试合并成一个条件表达式,并将这个表达式提炼成一个独立函数
3)、合并重复的条件片段
修改点:在条件表达式的每个分支上有着相同一段代码
做法:将这段重复代码搬移到条件表达式之外
4)、移除控制标记
修改点:在一系列布尔表达式中,某个变量带有“控制标记”(control flag)的作用。
做法:以break语句或return语句取代控制标记
bool isILoveYou=true;
int[] loveNum=new int[100];
for (int i=0; i < 100; i++) {
if (isILoveYou) {
if (某种原因) {
isILoveYou = false;
}
Console.WriteLine(loveNum[i]);
}
}
而isILoveYou就是控制标记,所以可以用continue,break,return这类跳出语句去移除控制标记
6)、以多态取代条件表达式
修改点:你手上有个条件表达式,它根据对象类型的不同而选择不同的行为
做法:将这个条件表达式的每个分支放进一个子类内的覆盖函数中,然后将原始函数声明为抽象函数。
原文链接:
https://www.gxlsystem.com/hulianwang-1510281.html
类图模式:
适配器模式:
类适配器
我今天买了机票,飞到香港迪士尼去游玩,晚上回到了酒店,想给我的笔记本电脑充电,但这时我发现,香港的插座是英式三角插座,我的充电器插不进去。这时我们就可以使用适配器模式,进行适配。
客户:中式插头,方法:英式插座,需要适配:中式插座
@AllArgsConstructor
@Data
public class ChineseStandard {
public String getChineseStandard() {
return "中式插座";
}
}
中式插座的类
public interface BritishStandard {
String getBritishStandard();
}
英式插座的接口
public class StandardAdapter extends ChineseStandard implements BritishStandard {
@Override
public String getBritishStandard() {
return this.getChineseStandard();
}
}
适配器,继承了中式英式,转换,当调英式插座的时候,返回的是中式插座。
插座
public class Notebook {
public void charge(BritishStandard britishStandard) {
if ("中式插座".equals(britishStandard.getBritishStandard())) {
System.out.println("充电成功!");
} else {
System.out.println("充电失败!");
}
}
}
客户类,笔记本电脑。
传进来英式插座的对象,如果得到中式插座,则充电成功
public class AdapterTest {
public static void main(String[] args) {
// 充电成功!
new Notebook().charge(new StandardAdapter());
}
}
测试类,传入适配器的对象。
成功将英式插座转换为中式插座。
所以适配器模式的任务:将源角色通过适配器角色转为目标角色,
目标角色(Target):该角色定义把其他类转换为何种接口,也就是我们的期望接口。
源角色(Adaptee):你想把谁转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。
适配器角色(Adapter):适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,它的职责非常简单:通过继承或是类关联的方式把源角色转换为目标角色。
————————————————
当前适配器模式部分出自:
原文链接:https://blog.csdn.net/weixin_51466332/article/details/123345199
对象适配器
通过实例对象(构造器传递)来实现适配器,而不是再用继承,其余基本同类适配器。
@AllArgsConstructor
public class StandardAdapter implements BritishStandard {
private ChineseStandard chineseStandard;
@Override
public String getBritishStandard() {
return chineseStandard.getChineseStandard();
}
}继承英式插座
在适配器中定义中式插座的对象,获取插座方法内 调用中式插座的方法
public class AdapterTest {
public static void main(String[] args) {
// 充电成功!
new Notebook().charge(new StandardAdapter(new ChineseStandard()));
}
}
接口适配器:
当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
public interface BritishStandard {
String getBritishStandard();
String getTypeC();
String getUSB();
}
插座适配器(适配器角色 Adapter)
将适配器定义成一个抽象接口
@AllArgsConstructor
public abstract class StandardAdapter extends ChineseStandard implements BritishStandard {
@Override
public String getBritishStandard() {
return null;
}
@Override
public String getTypeC() {
return null;
}
@Override
public String getUSB() {
return null;
}
}
public class AdapterTest {
public static void main(String[] args) {
StandardAdapter standardAdapter= new StandardAdapter() {
@Override
public String getBritishStandard() {
return new ChineseStandard().getChineseStandard();
}
};
// 充电成功!
new Notebook().charge(standardAdapter);
}
} 根据需要实现这个抽象接口
原文链接:https://blog.csdn.net/weixin_51466332/article/details/123345199
## 观察者模式
观察者模式又叫做发布-订阅(Publish/Subscribe)模式,订阅机制
聊天服务器消息队列订阅基于这个。
它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
观察者模式的主要的作用就是对对象解耦,将观察者和被观察者完全隔离。
实现观察者模式有很多形式,比较直观的一种是使用一种“注册—通知—撤销注册”的形式。
观察者;(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。
被观察者:被观察对象发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。
撤销观察:观察者告诉被观察者要撤销观察,被观察者从容器中将观察者去除。观察者将自己注册到被观察者的容器中时,被观察者不应该过问观察者的具体类型,而是应该使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么只要这个观察者也是相同的接口实现即可。一个被观察者可以对应多个观察者,当被观察者发生变化的时候,他可以将消息一一通知给所有的观察者。基于接口,而不是具体的实现,这一点为程序提供了更大的灵活性。
外观模式
用一个类执行三个独立的类的操作。对客户屏蔽此系统组件,减少客户处理对象数目,使得子系统的组件变化不会影响到调用它的客户类,只需调整外观。
在以下情况下可以使用外观模式:
• 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
• 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
• 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
(1) 外观模式应用于JDBC数据库操作
1 public class JDBCFacade {
2 private Connection conn=null;
3 private Statement statement=null;
4 public void open(String driver,String jdbcUrl,String userName,String userPwd) {
5 ......
6 }
7 public int executeUpdate(String sql) {
8 ......
9 }
10 public ResultSet executeQuery(String sql) {
11 ......
12 }
13 public void close() {
14 ......
15 }
16 }
(2) Session外观模式是外观模式在Java EE框架中的应用
模式扩展
一个系统有多个外观类
• 在外观模式中,通常只需要一个外观类,并且此外观类只有一个实例,换言之它是一个单例类。在很多情况下为了节约系统资源,一般将外观类设计为单例类。当然这并不意味着在整个系统里只能有一个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。
不要试图通过外观类为子系统增加新行为
• 不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。
外观模式与迪米特法则
• 外观模式创造出一个外观对象,将客户端所涉及的属于一个子系统的协作伙伴的数量减到最少,使得客户端与子系统内部的对象的相互作用被外观对象所取代。外观类充当了客户类与子系统类之间的“第三者”,降低了客户类与子系统类之间的耦合度,外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。
抽象外观类的引入
• 外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。
原文链接:https://www.cnblogs.com/WindSun/p/10263511.html
命令模式
又叫动作模式或事务模式,对象行为模式,将一个请求封装未对象,从而使可用不同的请求对客户进行参数化,
通过将请求封装到一个命令(Command)对象中,实现了请求调用者和具体实现者之间的解耦。如:CHAKAN CERT。
下发命令,调用请求。
将请求信息/报文配置/封装成命令。
在需要事务的系统中,可以选用命令模式。命令模式提供了对事务进行建模的方法。命令模式有一个别名就是Transaction。
命令模式结构:
抽象命令角色:Command: 接口,定义执行命令的接口。
具体命令角色:ConcreteCommand:通常会持有接收者对象,并调用接收者对象的相应功能来完成命令要执行的操作。
接收者(Receiver)角色:真正执行命令的对象。任何类都可能成为接收者,只要它能够实现命令要求实现的相应功能。
调用者(Invoker)角色:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。
参考:https://blog.csdn.net/bbj12345678/article/details/105076630
创建型设计模式(共五种)
创建对象的模式。又称生成器Builder
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
创建型模式提供了一种创建对象的机制,抽象实例化的过程,隐藏了对象的创建细节,对外只提供一个通用接口,能够提升已有代码的灵活性和可复性。
建造者模式:
https://blog.csdn.net/Small_Mouse0/article/details/66474580
一般建造者模式都有以下几种固定的角色:
抽象建造者(Builder)角色:给 出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者 (ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart1和 buildPart2),另一种是返还结构方法(retrieveResult)。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少 零件,就有多少相应的建造方法。
具体建造者(ConcreteBuilder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。这个角色要完成的任务包括:1.实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作。2.在建造过程完成后,提供产品的实例。
导演者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。
产品(Product)角色:产品便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的。
————————————————
版权声明:本文为CSDN博主「鼠晓」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Small_Mouse0/article/details/66474580
原型模式
:一个对象的产生可以不由零起步,直接从一个已经具备一定雏形的对象克隆,然后再修改为生产需要的对象。
本质是一种克隆对象的方法,其核心是重写Object中的clone方法,调用该方法可以在内存中进行对象拷贝。
原型模式有两种实现方式——浅拷贝和深拷贝
浅拷贝:当拷贝对象包含基本数据类型(如int、long)或者不可变的对象(如字符串、基本类型的包装类)时,会直接将这些属性复制到新的对象中。而原型对象中的引用对象会把内存中的地址复制给克隆对象。此时,两个对象共享了一个私有变量,你改我改大家都能改。
深拷贝:不管原型对象属性是简单数据类型还是引用对象类型都会完全的复制一份到新的对象中。两个对象之间互不影响。
原型模式的结构很简单
1、Prototype抽象原型类,声明了clone方法,它可以是接口或基类,一般情况下可以不用抽象原型类。因为万物皆对象,在Java中Object类是所有类的父类,Object类中有clone方法。
2、ConcretePrototype具体原型类,实现或者重写clone方法,通用代码如下:
1、原型模式是在内存中进行二进制流的拷贝,要比直接new一个对象性能好,特别是在一个循环体内创建大量对象时。
2、原型模式可以简化对象创建的过程,可以直接拷贝现有的原型实例的值,实现对象复用。
参考:
https://baijiahao.baidu.com/s?id=1730786729971289111&wfr=spider&for=pc
模板方法:
工程方法通常在模板方法中被调用。
待看