石河子做网站公司/重庆森林影评

石河子做网站公司,重庆森林影评,北京 网站建设600,企业网站的建立java规范总结1. Java 常见的代码规范1.1. Java 自带的工具方法1.1.1 比较两个对象是否相等1.1.2 apache commons工具类库1.1.2.1 字符串判空1.1.2.3 重复拼接字符串1.1.2.4 格式化日期1.1.2.4 包装临时对象 (不是特别常用)1.1.3 common-beanutils 操作对…

java规范总结

  • 1. Java 常见的代码规范
    • 1.1. Java 自带的工具方法
      • 1.1.1 比较两个对象是否相等
      • 1.1.2 apache commons工具类库
        • 1.1.2.1 字符串判空
        • 1.1.2.3 重复拼接字符串
        • 1.1.2.4 格式化日期
        • 1.1.2.4 包装临时对象 (不是特别常用)
      • 1.1.3 common-beanutils 操作对象
      • 1.1.3.1 commons-io 文件流处理
      • 1.1.4 Google Guava 工具类库
        • 1.1.4.1 创建集合
    • 1.2 java 常见的代码规范
      • 1.2.1 使用Collection.isEmpty() 检测空
      • 1.2.2 初始化集合时尽量指定其大小
      • 1.2.3 若需频繁调用Collection.contains 方法则使用Set
      • 1.2.4 使用静态代码块实现赋值静态成员变量
      • 1.2.5 工具类中屏蔽构造函数
      • 1.2.6 删除未使用的局部变量、方法参数、私有方法、字段和多余的括号
      • 1.2.8 字符串转化使用String.valueOf(value) 代替 " " + value (需补充)
      • 1.2.9 避免使用BigDecimal(double)
  • 2. 设计模式
    • 2.1 装饰者模式订阅
      • 2.1.1 定义
      • 2.1.2职责
      • 2.1.3 装饰模式结构
      • 2.1.3 举一个简单的例子
      • 2.1.4 另一个很经典的一个场景
      • 2.1.5 需求抽象出来
      • 2.1.6 具体的类图
      • 2.1.7 装饰模式的优点
      • 2.1.8 缺点
    • 2.2 桥接者模式
      • 2.2.1 桥接模式概念
      • 2.2.2 结构图
      • 2.2.3 具体代码
      • 2.2.4 桥接模式的设计要点和适用性
      • 2.2.5 装饰模式和桥接模式的区别
    • 2.3 观察者模式
    • 2.4 责任链模式
    • 2.5 建造者模式
      • 2.5.1 概念
    • 2.6 组合这模式
      • 2.6.1 组合模式的概念
      • 2.6.2 组合模式结构
      • 2.6.3组合模式工作分析
    • 2.7 策略模式
    • 2.8 外观模式
      • 2.8.1 概念
    • 2.9 命令模式
      • 2.9.1 概念
      • 2.9.2 模式结构
      • 2.9.3 结构图
      • 2.9.3建议看这个代码
      • 2.9.4 命令模式的优缺点

感谢分享:

1. Java 常见的代码规范

1.1. Java 自带的工具方法

1.1.1 比较两个对象是否相等

当我们用equals比较两个对象是否相等的时候,还需要对左边的对象进行判空,不然可能会报空指针异常,我们可以用java.util包下Objects封装好的比较是否相等的方法:

 Objects.equals(strA, strB); 

源码:

public static boolean equals(Object a, Object b) {  return (a == b) || (a != null && a.equals(b));  
}  

1.1.2 apache commons工具类库

apache commons是最强大的,也是使用最广泛的工具类库,里面的子库非常多,下面介绍几个最常用的

commons-lang,java.lang的增强版 建议使用commons-lang3,优化了一些api,原来的commons-lang已停止更新:

maven 的依赖:

org.apache.commons commons-lang3 3.12.0

1.1.2.1 字符串判空

传参CharSequence类型是String、StringBuilder、StringBuffer的父类,都可以直接下面方法判空,以下是源码:

public static boolean isEmpty(final CharSequence cs) {  return cs == null || cs.length() == 0;  
}  public static boolean isNotEmpty(final CharSequence cs) {  return !isEmpty(cs);  
}  // 判空的时候,会去除字符串中的空白字符,比如空格、换行、制表符  
public static boolean isBlank(final CharSequence cs) {  final int strLen = length(cs);  if (strLen == 0) {  return true;  }  for (int i = 0; i < strLen; i++) {  if (!Character.isWhitespace(cs.charAt(i))) {  return false;  }  }  return true;  
}  public static boolean isNotBlank(final CharSequence cs) {  return !isBlank(cs);  
}  

####1.1.2.2 首字母转大写 (这里可以查询源码看其他stringUtils 提供的其他源码,提供的新的特性)

String str = "yideng";  
String capitalize = StringUtils.capitalize(str);  
System.out.println(capitalize); // 输出Yideng  

1.1.2.3 重复拼接字符串

String str = StringUtils.repeat("ab", 2);  
System.out.println(str); // 输出abab  

1.1.2.4 格式化日期

再也不用手写SimpleDateFormat格式化了

// Date类型转String类型  
String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");  
System.out.println(date); // 输出 2021-05-01 01:01:01  // String类型转Date类型  
Date date = DateUtils.parseDate("2021-05-01 01:01:01", "yyyy-MM-dd HH:mm:ss");  // 计算一个小时后的日期  
Date date = DateUtils.addHours(new Date(), 1);  

1.1.2.4 包装临时对象 (不是特别常用)

当一个方法需要返回两个及以上字段时,我们一般会封装成一个临时对象返回,现在有了Pair和Triple就不需要了

// 返回两个字段  
ImmutablePair<Integer, String> pair = ImmutablePair.of(1, "yideng");  
System.out.println(pair.getLeft() + "," + pair.getRight()); // 输出 1,yideng  
// 返回三个字段  
ImmutableTriple<Integer, String, Date> triple = ImmutableTriple.of(1, "yideng", new Date());  
System.out.println(triple.getLeft() + "," + triple.getMiddle() + "," + triple.getRight()); // 输出 1,yideng,Wed Apr 07 23:30:00 CST 2021  

1.1.3 commons-collections 集合工具类

封装了集合判空的方法,以下是源码:

public static boolean isEmpty(final Collection<?> coll) {  return coll == null || coll.isEmpty();  
}  public static boolean isNotEmpty(final Collection<?> coll) {  return !isEmpty(coll);  
}  
// 两个集合取交集  
Collection<String> collection = CollectionUtils.retainAll(listA, listB);  
// 两个集合取并集  
Collection<String> collection = CollectionUtils.union(listA, listB);  
// 两个集合取差集  
Collection<String> collection = CollectionUtils.subtract(listA, listB);  

1.1.3 common-beanutils 操作对象

Maven依赖:

<dependency>  <groupId>commons-beanutils</groupId>  <artifactId>commons-beanutils</artifactId>  <version>1.9.4</version>  
</dependency>  
public class User {  private Integer id;  private String name;  
} 

设置对象属性

User user = new User();  
BeanUtils.setProperty(user, "id", 1);  
BeanUtils.setProperty(user, "name", "yideng");  
System.out.println(BeanUtils.getProperty(user, "name")); // 输出 yideng  
System.out.println(user); // 输出 {"id":1,"name":"yideng"}  

对象和map互转

// 对象转map  
Map<String, String> map = BeanUtils.describe(user);  
System.out.println(map); // 输出 {"id":"1","name":"yideng"}  
// map转对象  
User newUser = new User();  
BeanUtils.populate(newUser, map);  
System.out.println(newUser); // 输出 {"id":1,"name":"yideng"}  

1.1.3.1 commons-io 文件流处理

Maven依赖:

commons-io commons-io 2.8.0

文件处理

File file = new File("demo1.txt");  
// 读取文件  
List<String> lines = FileUtils.readLines(file, Charset.defaultCharset());  
// 写入文件  
FileUtils.writeLines(new File("demo2.txt"), lines);  
// 复制文件  
FileUtils.copyFile(srcFile, destFile);

1.1.4 Google Guava 工具类库

maven 依赖:

com.google.guava guava 30.1.1-jre

1.1.4.1 创建集合

List<String> list = Lists.newArrayList();  
List<Integer> list = Lists.newArrayList(1, 2, 3);  
// 反转list  
List<Integer> reverse = Lists.reverse(list);  
System.out.println(reverse); // 输出 [3, 2, 1]  
// list集合元素太多,可以分成若干个集合,每个集合10个元素  
List<List<Integer>> partition = Lists.partition(list, 10);  Map<String, String> map = Maps.newHashMap();  
Set<String> set = Sets.newHashSet();  

1.2 java 常见的代码规范

1.2.1 使用Collection.isEmpty() 检测空

​ 使用Collection.size() 来检测是否为空在逻辑上没有问题,但是使用Collection.isEmpty() 使得代码更易读,并且可以获得更好的性能;除此之外,任何Collection.isEmpty() 实现的时间复杂度都是O(1) ,不需要多次循环遍历,但是某些通过Collection.size() 方法实现的时间复杂度可能是O(n)。O(1)纬度减少循环次数 例子

反例:

LinkedList<Object> collection = new LinkedList<>();
if (collection.size() == 0){System.out.println("collection is empty.");}

正例

LinkedList<Object> collection = new LinkedList<>();
if (collection.isEmpty()){System.out.println("collection is empty.");}//检测是否为null 可以使用CollectionUtils.isEmpty()
if (CollectionUtils.isEmpty(collection)){System.out.println("collection is null.");

1.2.2 初始化集合时尽量指定其大小

尽量在初始化时指定集合的大小,能有效减少集合的扩容次数,因为集合每次扩容的时间复杂度很可能时O(n),耗费时间和性能。

反例

//初始化list,往list 中添加元素反例:
int[] arr = new int[]{1,2,3,4};
List<Integer> list = new ArrayList<>();
for (int i : arr){
list.add(i);
}

正例:

//初始化list,往list 中添加元素正例:
int[] arr = new int[]{1,2,3,4};
//指定集合list 的容量大小List<Integer> list = new ArrayList<>(arr.length);
for (int i : arr){
list.add(i);}

1.2.3 若需频繁调用Collection.contains 方法则使用Set

在Java 集合类库中,List的contains 方法普遍时间复杂度为O(n),若代码中需要频繁调用contains 方法查找数据则先将集合list 转换成HashSet 实现,将O(n) 的时间复杂度将为O(1)。

反例:

//频繁调用Collection.contains() 反例
List<Object> list = new ArrayList<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++){
//时间复杂度为O(n)
if (list.contains(i))System.out.println("list contains "+ i);}

正例:

//频繁调用Collection.contains() 正例List<Object> list = new ArrayList<>();Set<Object> set = new HashSet<>();
for (int i = 0; i <= Integer.MAX_VALUE; i++){
//时间复杂度为O(1)
if (set.contains(i)){System.out.println("list contains "+ i);}}

1.2.4 使用静态代码块实现赋值静态成员变量

对于集合类型的静态成员变量,应该使用静态代码块赋值,而不是使用集合实现来赋值。

反例:

//赋值静态成员变量反例
private static Map<String, Integer> map = new HashMap<String, Integer>(){{
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);}};
private static List<String> list = new ArrayList<>(){{
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");}};

正例:

//赋值静态成员变量正例
private static Map<String, Integer> map = new HashMap<String, Integer>();
static {
map.put("Leo",1);
map.put("Family-loving",2);
map.put("Cold on the out side passionate on the inside",3);}private static List<String> list = new ArrayList<>();
static {
list.add("Sagittarius");
list.add("Charming");
list.add("Perfectionist");}

1.2.5 工具类中屏蔽构造函数

工具类是一堆静态字段和函数的集合,其不应该被实例化;但是,Java 为每个没有明确定义构造函数的类添加了一个隐式公有构造函数,为了避免不必要的实例化,应该显式定义私有构造函数来屏蔽这个隐式公有构造函数。

反例:

public class PasswordUtils {
//工具类构造函数反例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();}

正例:

public class PasswordUtils {
//工具类构造函数正例
private static final Logger LOG = LoggerFactory.getLogger(PasswordUtils.class);//定义私有构造函数来屏蔽这个隐式公有构造函数
private PasswordUtils(){}public static final String DEFAULT_CRYPT_ALGO = "PBEWithMD5AndDES";public static String encryptPassword(String aPassword) throws IOException {
return new PasswordUtils(aPassword).encrypt();}

1.2.6 删除未使用的局部变量、方法参数、私有方法、字段和多余的括号

### 1.2.7  **删除多余的异常捕获并抛出 ** (需补充)

用catch 语句捕获异常后,若什么也不进行处理,就只是让异常重新抛出,这跟不捕获异常的效果一样,可以删除这块代码或添加别的处理。

//多余异常反例
private static String fileReader(String fileName)throws IOException{try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {builder.append(line);}
return builder.toString();} catch (Exception e) {
//仅仅是重复抛异常 未作任何处理
throw e;}
}

正例:

//多余异常正例
private static String fileReader(String fileName)throws IOException{try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {builder.append(line);}
return builder.toString();
//删除多余的抛异常,或增加其他处理:
/*catch (Exception e) {return "fileReader exception";}*/}
}

1.2.8 字符串转化使用String.valueOf(value) 代替 " " + value (需补充)

把其它对象或类型转化为字符串时,使用String.valueOf(value) 比 “”+value 的效率更高。

反例:

//把其它对象或类型转化为字符串反例:
int num = 520;
// "" + value
String strLove = "" + num;

正例:

//把其它对象或类型转化为字符串正例:
int num = 520;
// String.valueOf() 效率更高
String strLove = String.valueOf(num);

1.2.9 避免使用BigDecimal(double)

BigDecimal(double) 存在精度损失风险,在精确计算或值比较的场景中可能会导致业务逻辑异常。

反例:

// BigDecimal 反例
BigDecimal bigDecimal = new BigDecimal(0.11D);

正例:

// BigDecimal 正例
BigDecimal bigDecimal1 = bigDecimal.valueOf(0.11D);

2. 设计模式

2.1 装饰者模式订阅

2.1.1 定义

装饰模式又称,包装模式。装饰模式是以客户端透明的方式扩展对象的功能 是一种继承的替代方案。

2.1.2职责

  • 动态给对象增加新的功能
  • 装饰模式是一种用于替代,继承的技术,无需通过继承增加子类就能扩展 对象的功能。使用对象的关联关系,替代继承关系 更加灵活,同时避免了体系的膨胀。

2.1.3 装饰模式结构

  • 装饰模式类图
image-20220311003942157
  • Component 抽象构建角色 :真是对象(对应上图 ConcreteOperation() 对象)和装饰对象具有相同的接口

    。这样客户端对象就能以与 真是对象相同的方式同装饰对象交互了。

  • ConcreteComponent 具体构建的角色(真是对象) :定义一个接收附加责任的类。

  • Decorator装饰角色 持有构建角色的引用。装饰对象接收客户端的请求,并把这些请求转发给真是的对象。这样,就能在真是对象调用前后增加新的功能。

  • ConcreteDecorate 具体的装饰角色:负责给构建对象增加新的功能。

2.1.3 举一个简单的例子

举一个简单的汽车例子,创造每一种汽车都需要继承父类进行实现,如下图 那么当我们需要,既能路上行驶,又能水上行驶,又得继承父类。

image-20220311003942157

以后每增加一种新功能的汽车都需要增一个类,这样的话会创建大量的类。这时候就能使用装饰类了。

代码示例:

抽象构件

public interface AbstractCar {void move();
}  

具体构建

public class Car implements AbstractCar{public void move() {System.out.println("路上行驶");}
}

装饰角色

public class SuperCar implements AbstractCar{protected AbstractCar car;public SuperCar(AbstractCar car){this.car=car;}public void move() {car.move();}}

具体装饰 角色

/*** 飞行汽车  
*/   ublic class FlyCar extends SuperCar{public FlyCar(AbstractCar car) {super(car);}public void fly() {System.out.println("空中行驶汽车");}@Overridepublic void move() {super.move();fly();}}/*** 水上汽车*/
public class WaterCar extends SuperCar{public WaterCar(AbstractCar car) {super(car);}public void swim() {System.out.println("水上行驶汽车");}@Overridepublic void move() {super.move();swim();}}

客户端

public class Client {public static void main(String[] args) {Car car=new Car();car.move();System.out.println("------增加新功能,飞行------");FlyCar flyCar=new FlyCar(car);flyCar.move();System.out.println("------新增加功能,水上行驶-----");WaterCar waterCar=new WaterCar(car);waterCar.move();System.out.println("-----新增加两个功能,飞行与水上行驶-----");WaterCar waterCar2=new WaterCar(flyCar);waterCar2.move();}}//输出结果
路上行驶
------增加新功能,飞行------
路上行驶
空中行驶汽车
------新增加功能,水上行驶-----
路上行驶
水上行驶汽车
-----新增加两个功能,飞行与水上行驶-----
路上行驶
空中行驶汽车
水上行驶汽车

2.1.4 另一个很经典的一个场景

  • 咖啡类型 espresso(意大利咖啡),shortblack,LongBlack(美食咖啡),Decaf(无因咖啡)
  • 调料 Milk ,Soy(豆浆),Chocolate
  • 费用 不同的咖啡价格是不同的,而且有 咖啡+调料的类型组合 每个咖啡,都有自己的单价,咖啡+调料也有自己的单价。
  • 要求 扩展咖啡的种类的时候,具有很好的扩展性,改动方便,维护方便。
  • 总结:看到需求,首先是问题的抽象能力,将问题抽象出来,这个抽象能力非常重要。

2.1.5 需求抽象出来

  1. 看到每个咖啡,都有自己的cost(花费)和description(描述)可以知道咖啡共有的属性和行为。
  2. 看到问题后,手动画图或者用软件画出类图 ,遇到问题,首先是下手,做软件行业,就是要下手设计,大家都能想到的如下类图设计
image-20220302212850518

咖啡类型就像是构件,调料就是具体的装饰类,给构件增加新的功能;

2.1.6 具体的类图

装饰者模式,更像俄罗斯的套娃,一层一层的嵌套
看到类图后你会发现,其实就 当前类A 中 含有A属性。
类图如下:

image-20220311003942157

代码: 见idea

2.1.7 装饰模式的优点

  • 扩展对象功能,比继承灵活,不会导致类个数急剧增加。
  • 可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象。
  • 具体构 件 类和具体装饰类可以独立变化,用户可以根据需要自己增加新的 具体构件子类和具体装饰子类。

2.1.8 缺点

  • 产生很多小对象。大量小的对象占据内存,一定程度上影响性能。
  • 装饰模式易出错,调试排查比较麻烦。

2.2 桥接者模式

商城中常见的模式 ,以电脑分类,如何处理商品分类销售问题

  • 我们可以使用多层继承实现关系如下

    image-20220311010813084

代码省略: 存在的问题,

  • 扩展问题

    1. 如果要增加新的电脑类型:如平板电脑,则要增加 各个品牌下面的类。
    2. 如果新增加品牌,也要增加各个电脑下的类。
    • 违反了单一职责原则

    ​ 一个类:如联想笔记本电脑,有两个引起这个类变化的原因:品牌及电脑的类型。

    总结:某些由于自身的逻辑,它具有两个或者多个维度的变化,为了应对这种“多维度变化”,并且利用面向对象 的技术来,使得该类能轻松的沿着多个方向变化,而有不引入额外的复杂度。引入bridge模式。

2.2.1 桥接模式概念

概念:把抽象(abstraction)和行为实现分开(implement)从而保持各部分的独立性以及对功能的扩展

2.2.2 结构图

image-20220311012335063

上面场景中有两个变化的维度,电脑类型和电脑品牌,将上面的代码通过桥接模式实现:

2.2.3 具体代码

电脑品牌维度

/*** 电脑品牌维度接口*/
public interface Brand {void nane();
}class Lenovo implements Brand{@Overridepublic void nane() {System.out.println("联想电脑");}
}class Dell implements Brand{@Overridepublic void nane() {System.out.println("戴尔电脑");}
}

电脑类型维度

/*** 电脑类型维度*/
public class Computer{protected Brand brand;public Computer(Brand brand){this.brand=brand;}public void sale(){brand.nane();}
}
class Desktop extends Computer{public Desktop(Brand brand) {super(brand);}@Overridepublic void sale() {super.sale();System.out.println("销售台式机");}
}class Laptop extends Computer{public Laptop(Brand brand) {super(brand);}@Overridepublic void sale() {super.sale();System.out.println("销售笔记本");}}

客户端

/*** 客户端*/
public class Client {public static void main(String[] args) {Computer len=new Desktop(new Lenovo());len.sale();}
}//输出结果
联想电脑
销售台式机

总结:这样将 电脑品牌和电脑类型两个维度,分离开并且组合使用,这样在增加品牌或类型更加简单。

2.2.4 桥接模式的设计要点和适用性

  • 设计要点

处理多层继承结构,处理多维度变化的场景,将更维度设计成独立的继承模块,使各个维度可以独立扩展在抽象层。

  • 适用性

    1. 如果一个系统需要在构件的抽象化角色和具体化角色之间,增加更多的灵活性,避免在两个层次之间建立静态的关系。
    2. 设计要求实现化角色的任何改变不应该影响客户端,或者说实现化角色的改变对客户端是完全透明的。
    3. 一个构件多余一个抽象化角色和实现化角色,系统需要它们之间互相解耦。
    4. 虽然系统中使用继承没有问题,但由于抽象化角色和具体化角色需要独立化,设计要求独立管理两者。

2.2.5 装饰模式和桥接模式的区别

  • 两个模式都是为了解决过多子类对象的问题。但他们的诱因不同,桥接模式是对象自身现有机制沿着多个维度变化,是既有部分不稳定。装饰模式是为了增加新的功能

2.3 观察者模式

场景: 是一种 一对多的关系,进一步理解为 消息订阅模式

Subject 被观察者 也叫做 主题
Observer  观察者  也叫订阅者
理解:被观察者 通知观察者自己的状态变化   被观察者中注册了,多个观察者对象。

2.4 责任链模式

2.5 建造者模式

2.5.1 概念

将复杂对象的构建和它的表示,使得同样的构建过程有不同的创建方式。

2.6 组合这模式

2.6.1 组合模式的概念

概念 把部分和整体用树形结构来表示 ,从而使客户端可以使用统一的方式对,部分对象和整体对象就行管理。

2.6.2 组合模式结构

抽象构件(Conponent) 角色: 所有类共有接口,定义叶子节点和容器共同点

叶子(Leaf)构件角色:在组合中表示叶子节点对象,叶子节点五子节点。

容器(Composite)构件角色: 有容器特征,可以用来存储子节点,在Component接口中实现与子节点有关操作,如增加(add)和删除(remove)等。

image-20220312192645979

2.6.3组合模式工作分析

  • 组合模式为处理树形结构,提供了完美的解决方案,描述了如何将容器和叶子节点进行递归组合,使得用户在使用时, 可以一致性的对待容器和叶子。
  • 当容器对象的指定方法被调用时,将遍历整个树形结构,寻找包含这个方法的成员,并调用执行。其中使用递归调用机制对整个机构进行处理。

下面是通过简单秒杀的例子,使用组合

抽象构建

public interface AbstractFile {void killVirus();//杀毒
}

叶子构件

class ImageFile implements AbstractFile{private String name;public ImageFile(String name){this.name=name;}public void killVirus() {System.out.println("---对图像文件"+name+"杀毒");}}
class TextFile implements AbstractFile{private String name;public TextFile(String name){this.name=name;}public void killVirus() {System.out.println("---对文本文件"+name+"杀毒");}}

容器构建

class Folder implements AbstractFile{private String name;private ArrayList<AbstractFile> list=new ArrayList<AbstractFile>();public Folder(String name){this.name=name;}public void add(AbstractFile file){list.add(file);}public void remove(AbstractFile file){list.remove(file);}public AbstractFile getChild(int index){return list.get(index);}public void killVirus() {System.out.println("---对文件夹"+name+"杀毒");for(AbstractFile file:list){file.killVirus();}}}

客户端

public class Client {public static void main(String[] args) {Folder f1;AbstractFile f2,f3;f1=new Folder("我的收藏");f2=new ImageFile("my.jpg");f3=new TextFile("my.txt");f1.add(f2);f1.add(f3);f1.killVirus();}}//输出结果:
---对文件夹我的收藏杀毒
---对图像文件my.jpg杀毒
---对文本文件my.txt杀毒  

2.7 策略模式

组合关系

2.8 外观模式

2.8.1 概念

  • 外观模式(也称门面模式)定义了一个高层接口,为子系统中的一组接口提供了,一致的界面,从而使子系统更加容易使用。

2.9 命令模式

2.9.1 概念

将一个请求封装为对象,从而使我们可用不同的请求,对客户进行参数化;对请求排队或者记录请求日志,以及支持撤销操作,以及支持撤销操作。也称为:动作(Action)模式,事务(transaction)模式。

2.9.2 模式结构

  • Conmmand 抽象命令类: 声明执行操作接口

  • ConcreteCommand 具体命令类:通常持有 一个接收者对象并绑定一个动作,调用接收者相应的动作,以实现execute方法。

  • invoker 调用者/请求者:请求的发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联。在程序运行时,将调用命令对象的execute() 间接调用接收者的相关工作。

  • Receiver接收者:接受者执行与请求相关的操作,具体实现对请求业务的处理。

2.9.3 结构图

在这里插入图片描述

Receiver接受者

/*** 真正的命令执行者*/
public class Receiver {public void action(){System.out.println("执行命令----");}public void unAction(){System.out.println("撤销命令----");}}

command 抽象命令类

/*** 抽象命令接口*/
public interface Command {void  execute();//执行命令void  cancel();//取消命令 }   

ConcreteCommand具体命令类

/*** 具体命令类*/
public class ConcreteCommand implements Command{private Receiver receiver;public ConcreteCommand(Receiver receiver) {super();this.receiver = receiver;}public void execute() {//可进行执行命令前相关操作receiver.action();//执行命令//可进行执行命令后相关操作}public void cancel() {receiver.unAction();}
}

Invoke 调用者/请求者

public class Invoker {private Command command;  //可以是多个命令public Invoker(Command command) {super();this.command = command;}//执行命令public void runCommand(){command.execute();}//取消命令public void cancelCommand(){command.cancel();}}

客户端

public class Client {public static void main(String[] args) {//创建接收者Receiver receiver=new Receiver();//创建命令对象,并设置接收者Command command=new ConcreteCommand(receiver);//创建调用者,设置命令Invoker invoker=new Invoker(command);invoker.runCommand();invoker.cancelCommand();}
}//输出结果
执行命令---- 
撤销命令----   

2.9.3建议看这个代码

应用 :模拟对电视机的操作有开机、关机、换台命令。代码如下

//执行命令的接口
public interface Command {void execute();
}
//命令接收者Receiver
public class Tv {public int currentChannel = 0;public void turnOn() {System.out.println("The televisino is on.");}public void turnOff() {System.out.println("The television is off.");}public void changeChannel(int channel) {this.currentChannel = channel;System.out.println("Now TV channel is " + channel);}
}
//开机命令ConcreteCommand
public class CommandOn implements Command {private Tv myTv;public CommandOn(Tv tv) {myTv = tv;}public void execute() {myTv.turnOn();}
}
//关机命令ConcreteCommand
public class CommandOff implements Command {private Tv myTv;public CommandOff(Tv tv) {myTv = tv;}public void execute() {myTv.turnOff();}
}
//频道切换命令ConcreteCommand
public class CommandChange implements Command {private Tv myTv;private int channel;public CommandChange(Tv tv, int channel) {myTv = tv;this.channel = channel;}public void execute() {myTv.changeChannel(channel);}
}
//可以看作是遥控器Invoker
public class Control {private Command onCommand, offCommand, changeChannel;public Control(Command on, Command off, Command channel) {onCommand = on;offCommand = off;changeChannel = channel;}public void turnOn() {onCommand.execute();}public void turnOff() {offCommand.execute();}public void changeChannel() {changeChannel.execute();}
}
//测试类Client
public class Client {public static void main(String[] args) {// 命令接收者ReceiverTv myTv = new Tv();// 开机命令ConcreteCommondCommandOn on = new CommandOn(myTv);// 关机命令ConcreteCommondCommandOff off = new CommandOff(myTv);// 频道切换命令ConcreteCommondCommandChange channel = new CommandChange(myTv, 2);// 命令控制对象InvokerControl control = new Control(on, off, channel);// 开机control.turnOn();// 切换频道control.changeChannel();// 关机control.turnOff();}
}

执行结果

The televisino is on.
Now TV channel is 2
The television is off.

2.9.4 命令模式的优缺点

  • 优点
  1. 降低对象的耦合度。
  2. 新的命令很容易加入到系统中。
  3. 可以很容易的设计一套命令。
  4. 调用同一个方法不同功能
  • 缺点
  1. 使用命令模式可能会导致某些系统有很多具体的命令类,因为针对每一个命令需要设计一个命令类,因此某些系统可能需要大量的命令类,将影响命令模式的使用。
  • 总结

    1. 命令模式本质是对,命令进行封装,将发出命令的责任和执行命令的责任分割开。
    2. 每一个命令都是一个操作,请求一方发出命令,要求执行一个动作;接收方收到请求,并执行请求。
    3. 命令模式允许请求的一方和接收的一方,独立开来,使得请求方不知道接收方的接口,更不知道请求是怎么被接收,以及是否被执行,何时被执行,以及怎么被执行。
    4. 命令模式使请求本身成为对象,这个对象和其他对象可以被存储和传递。
    5. 命令模式的关键在于引入抽象接口,且发送者针对抽象接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/423001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SharePoint要在master page中动态显示List数据的几种方式

我们都知道&#xff0c;在SharePoint中&#xff0c;Content page继承自Page layout&#xff0c;而Page layout又继承自Master page。Master page的作用大家都知道&#xff0c;它定义了站点的的整体外观和公共元素&#xff0c;因此有了很强的页面重用性和很好的页面编辑体验&…

前端学习(179):表单元素

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/ html4/strict.dtd"> <html><head><meta http-equiv"content-type" content"text/html; charsetutf-8"><title>表单</ti…

【软件开发底层知识修炼】十二 C/C++语言中内嵌汇编语言(asm)

上一篇文章学习了链接脚本的语法与相关概念&#xff1a;链接脚本的概念 在继续学习链接器的内容的同时&#xff0c;先学习一个新内容&#xff1a;内嵌汇编。 GCC编译器一般支持C/C内嵌汇编语言&#xff0c;这样可以实现语言本身无法实现的内容。我们本文主要介绍C语言中的内嵌…

数据思维整理

数据思维整理分享

windows7下iis网站的.net框架版本设置

昨天下载了 VS2010 创建了一个默认的WebApplication&#xff0c;想看看在iis中运行的情况&#xff0c;虽说用了几个月的 win7 &#xff0c;但还从没有用过IIS。首先给人的感觉是IIS变化很大&#xff0c;多出了很多东西&#xff0c;让人感到很茫然。 先建个网站试试&#xff0c;…

【OS学习笔记】二十三 保护模式七:保护模式下任务的隔离与任务的特权级概念

上一篇文章学习了保护模式下操作系统内核如何加载程序并运行&#xff1a;点击链接查看上一篇文章 本篇文章接着上一篇文章学习保护模式下任务的隔离。 包括以下学习内容&#xff1a; 任务的全局空间和局部空间任务的TSS任务的LDT任务的特权级概念等 1、回顾 在保护模式下&…

[Drupal] How to add the js file and js code block in Drupal

Drupal 6:代码//This will add a JS file to your head (specifically the $scripts variable in page.tpl.php)drupal_add_js(drupal_get_path(module,my_module) ./my_module.js); //This add inline JS to the head of the documentdrupal_add_js(alert("Hello!"…

【OS学习笔记】二十四 保护模式七:调用门与依从的代码段----特权级保护

学习交流加 个人qq&#xff1a; 1126137994个人微信&#xff1a; liu1126137994学习交流资源分享qq群&#xff1a; 962535112 上一篇文章学习了保护模式下的任务与任务隔离&#xff0c;以及简单介绍了保护模式下的特权级的概念。点击链接查看上一篇文章&#xff1a;任务与任务隔…

【OS学习笔记】二十六 保护模式八:任务门---任务切换

上一篇文章学习了&#xff1a;保护模式七&#xff1a;调用门与依从的代码段----特权级保护 主要学习了以下内容&#xff1a; 描述符特权级&#xff08;目标对象的特权级&#xff09;DPL 描述符特权级&#xff08;目标对象的特权级&#xff09;DPL 当前特权级CPL 低特权级的应…

腾讯微博应用

腾讯微博开放平台提供了一些官方微博应用&#xff0c;供开发者借鉴和利用&#xff0c;其中包括&#xff1a; 一键转播——嵌入一键转播到你的网站里&#xff0c;访客便能将网页信息直接传播至腾讯微博。分享资讯的同时&#xff0c;用户通过来源链接可进入你的网站&#xff0c;从…

【OS学习笔记】二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套

上一篇文章学习了任务门的概念&#xff1a;任务门—任务切换。主要学习了以下内容&#xff1a; 使用任务门进行任务切换的一般工作原理&#xff08;和中断有关的任务切换&#xff09; 本篇文章接着上一篇文章学习以下内容&#xff1a; 利用jmp进行任务切换利用call进行任务切…

Windows Phone 7 开发 31 日谈——第22日:应用?还是 游戏?

本文是“Windows Phone 7 开发 31 日谈”系列的第22日。 昨天&#xff0c;我发了一篇极长的关于Silverlight Toolkit for Windows Phone的文章。今天的会短一些&#xff0c;但却非常珍贵。我会讨论你的应用程序设置中非常细微但很重要的设置&#xff1a;类别&#xff08;Genre&…

《Advanced .NET Debugging》 读书笔记 Listing 3-6: 使用sxe在程序载入mscorwks之后停下来载入sos...

1. 在WinDbg下载入01MDASample.exe 2. 执行 sxe ld mscorwks.dll 该命令的作用是在进程载入mscorwks之后停下来 3. 执行 g 可见程序在载入mscorwks.dll 之后停下来了 4. 执行 .loadby sos.dll mscorwks 转载于:https://www.cnblogs.com/charrli/archive/2010/12/25/1916964.h…

转载并学习实现三重DES加密解密代码(一)

作者:finallyliuyu 出处&#xff1a;博客园 声明&#xff1a;此篇博文代码来自于邹德强先生。由于目前找到的版本是残缺版&#xff0c;所以我又进行了补全。读一份好代码&#xff0c;可以领略到作者的编程风格和语言驾驭能力&#xff0c;同时又能从其中汲取养分。现将我所修改后…

【OS学习笔记】三十 保护模式九:段页式内存管理机制概述

上几篇文章学习了任务切换相关知识&#xff0c;如下&#xff1a; 【OS学习笔记】二十六 保护模式八&#xff1a;任务门—任务切换【OS学习笔记】二十七 保护模式八&#xff1a;任务切换的方法之----jmp与call的区别以及任务的中断嵌套 今天继续学习保护模式下的分页机制。本篇…

真人拳皇项目第六次Scrum总结——史经浩

今天&#xff0c;我们组开始了正式的编码阶段&#xff0c;前期plan的时候天马行空&#xff0c;现在是脚踏实地的coding了。在Scrum上&#xff0c;大家sync了一下各自的进展&#xff0c;如下&#xff1a; 今天 进度 问题及解决 明天 田飞 work item 37528:DirectX动画的de…

【OS学习笔记】三十一 保护模式九:页目录、页表和页三者的关系详解

上一篇文章学习了&#xff1a;保护模式九&#xff1a;段页式内存管理机制概述 本篇文章接着学习以下内容&#xff1a; 页目录概念页表概念页目录、页表与页之间的关系虚拟地址&#xff08;线性地址&#xff09;到物理地址的具体变换过程。 1、页目录、页表和页的对应关系 第…

使用某个文件夹下的所有文件去替换另一个文件夹下及其子文件夹下存在的同名文件(Python实现)...

值此新年即将到来之际,在这献上今年最后一篇文章. 产生这个需求是在项目的一次图标替换上,当时给了我一堆新图标要替换原来的老图标,可是原来的老图标分布在某个文件夹下的各个子文件夹下面,而新图标全是在同一个目录下的. 手动替换的话,只能是搜索文件名后替换,但是文件很多太…

一款研发管理软件的对象标签介绍

如果你了解WIKI&#xff0c;WIKI中的所有信息链接以标签的方式网状关联。TOPO系统中实现了完整的TAG功能&#xff0c;区别于目前市面上的其他类似管理系统&#xff0c;TOPO系统中实现的标签功能更加彻底和全面&#xff0c;例如完全用户自定义TAG&#xff0c;系统中所有管理对象…

【OS学习笔记】三十四 保护模式十:中断和异常区别

上几篇文章学习了分页机制的一些原理&#xff1a; 【OS学习笔记】三十 保护模式九&#xff1a;段页式内存管理机制概述【OS学习笔记】三十一 保护模式九&#xff1a;页目录、页表和页三者的关系详解 今天继续学习保护模式下的关于中断与异常的概念。本文主要学习中断与异常的…