大话设计者模式
文章目录
第一章 简单工厂模式:
1.特点
i. 代码编写过程中要注意松耦合,所以客户端要和业务端分离,业务端的修改不会影响客户端的代码 : 高内聚,低耦合
ii. facotory中所能new的对象需要有共性,多为继承相同的父类,或共用接口
iii.简单工厂模式,是通过一个factory类来创建所需要的对象
iv.如果需要修改只需要重写实现类,并部署到工厂里即可
2. 完整代码分析
// 代码编写过程中要注意松耦合,所以客户端要和业务端分离,业务端的修改不会影响客户端的代码 : 高内聚,低耦合
public class Client {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数字A:");
String numA = sc.next();
System.out.println("请输入数字B:");
String numB = sc.next();
System.out.println("请选择运算符号:+ - * /");
String operator = sc.next();
Operation operation = OperatorFactory.getOperator(operator);
System.out.println(operation.operate(numA, numB));
}
}
//ii. facotory中所能new的对象需要有共性,多为继承相同的父类,或共用接口
public interface Operation {
String operate(String numA, String numB);
}
//iii. 简单工厂模式,是通过一个factory类来创建所需要的对象
public class OperatorFactory {
public static Operation getOperator(String operator){
Operation operation = null;
switch (operator) {
case "+":
operation = new AddOperation();
break;
case "-":
operation = new SubOperation();
break;
case "*":
operation = new MutOperation();
break;
case "/":
operation = new DivOperation();
break;
}
return operation;
}
}
//实现类
public class DivOperation implements Operation {
@Override
public String operate(String numA, String numB) {
if (Double.parseDouble(numB) != 0) {
double result = Double.parseDouble(numA) / Double.parseDouble(numB);
return result + "";
} else {
return "被除数不能为0";
}
}
}
public class MutOperation implements Operation {
@Override
public String operate(String numA, String numB) {
double result = Double.parseDouble(numA) + Double.parseDouble(numB);
return result +"";
}
}
public class SubOperation implements Operation {
@Override
public String operate(String numA, String numB) {
double result = Double.parseDouble(numA) - Double.parseDouble(numB);
return result +"";
}
}
public class AddOperation implements Operation {
@Override
public String operate(String numA, String numB) {
double result = Double.parseDouble(numA) + Double.parseDouble(numB);
return result +"";
}
}
第二章 策略模式
1. 特点
策略模式(strategy):他定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不影响到使用算法的客户.
具体表现为:通过重写父类接口的抽象算法而创建出具体实现类算法. 再通过创建一个context(上下文),来将这些具体策略进行封装调用.在context 构造器中创建strategy的实现类对象,从而完成最终对实现类方法的调用.
)]
2. 完整代码分析
A. 单独策略模式
public class CashContext {
// The following is typical strategy model
private CashSuper cashSuper;
public CashContext(CashSuper cashSuper) {
this.cashSuper = cashSuper;
}
public void getCashAmount(double money) {
String result = cashSuper.getResult(money);
System.out.println("result = " + result);
}
}
B. 策略模式与工厂模式混合
此模式能进一步解耦,从而达到在客户端只有一个调用方法而不知道具体实现逻辑
// Strategy 接口
public interface CashSuper {
String getResult(double money);
}
//Strategy 实现类
public class CashDiscountImpl implements CashSuper {
@Override
public String getResult(double money) {
return "discount";
}
}
public class CashNormalImpl implements CashSuper {
@Override
public String getResult(double money) {
return "normal";
}
}
public class CashRebateImpl implements CashSuper {
@Override
public String getResult(double money) {
return "rebate";
}
}
//context 结合工厂模式:
public class CashContext {
private CashSuper cashSuper = null;
public CashContext(String type) {
switch (type) {
case "normal":
cashSuper = new CashNormalImpl();
break;
case "rebate":
cashSuper = new CashRebateImpl();
break;
case "discount":
cashSuper = new CashDiscountImpl();
break;
default:
break;
}
}
public void cashResult(double money){
String result = cashSuper.getResult(money);
System.out.println(result);
}
}
//客户端
public class Client {
public static void main(String[] args) {
CashContext cashContext = new CashContext(Type.REBATE.getName());
cashContext.cashResult(100);
}
}
//创建了个枚举用于练习的目的.枚举相当于static final 常量
public enum Type {
NORMAL("normal"), REBATE("rebate"), DISCOUNT("discount");
private String name;
Type(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3.策略工厂模式与工厂模式区别
刚看完策略工厂模式一开始觉得和工厂模式没有什么区别后来再网上看了各个大神的总结,瞬间醍醐灌顶
工厂模式:只是负责为调用者创建所需要的实体类,具体如何使用实体类以及对类方法调用由调用者来决定
策略模式:通过context封装了一系列策略,从而产生一个新方法. 调用者只需要调用这一个方法,就可以完成不同策略.但是调用者需要告知context 调用哪一个策略,因此耦合性会升高.(可参考2A.单独使用策略模式例子,调用者再调用时传入的是一个具体实现类对象)
策略工厂模式:对策率模式进行了解耦,不需要由调用者来创建对象,而是传入String type 参数后,由context 自行创建对象,从而达到了解耦的效果.(参见:2B)
吃水不忘挖井人,下面是看到大神的总结.字字珠玑.
第三章 单一职责
1.原则
1.就一个类而言,应该仅有一个引起他变化的原因
2.如果一个类承担的职责过多, 就等于把这些职责耦合了一个职责的变化会削弱或抑制这个类完成其他职责的能力.这种耦合会导致脆弱的设计
当变化发生时,设计会遭受到意想不到的破坏
2.理解
类的创建应该是为某一类相似事物而建立的. 在进行程序设计的过程中,不应该在同一个类中放入过多的方法.类中应该只放针对一种事物(一类逻辑)变化而产生对应结果的方法.
第四章 开放封闭
1.原则
1. 对于扩展时开放即可以通过对类,模块,方法进行增强实现来扩展.
2. 对于更改是封闭的.
3. 开放-封闭原则是面向对象设计的核心所在.遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可拓展,可复用,灵活性好.开发人员应该仅对程序中陈概念出品换变化的那些部分做出抽象.但是同时如果对于程序中的每个部分都刻意进行抽象同样不可取. 拒绝不成熟的抽象和抽象本身一样重要.
2.应用
1. 因为无法做到完全的封闭,所以设计人员必须要一种对未来变化的预判.对预判构造抽象来隔离变化.并通过对抽象的实现来扩展程序
2. 在需求发生变化后,要分析判断对新的变化构造新的抽象.要注意我们希望在开发工作展开不久就能知道可能发生的变化.查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难.
3.面对需求,对程序的改动时增加新代码进行,而不是更改现有的代码.
3.理解
开放原则: 以java为例,Java中通过对类和接口的继承,多态的方式达到了OOP的开放原则.多数情况下可以通过对接口的实现类来完成新的变动需求.如果现有设计中没有针对新需求的直接接口,可以先考虑是否能通过复合或者其他设计模式对现有的实现类对象组合增强来完成,如果没有则将此需求抽象隔离成一个新的接口.具体是否抽象隔离,要更具具体业务判断.
封闭原则: java 类的封装是这一原则的体现.同时项目完成后,如果业务需求发生变动,需要通过增加新代码来增加改进,而不是对现有代码改写.
行,而不是更改现有的代码.
#### 3.理解
```markdown
开放原则: 以java为例,Java中通过对类和接口的继承,多态的方式达到了OOP的开放原则.多数情况下可以通过对接口的实现类来完成新的变动需求.如果现有设计中没有针对新需求的直接接口,可以先考虑是否能通过复合或者其他设计模式对现有的实现类对象组合增强来完成,如果没有则将此需求抽象隔离成一个新的接口.具体是否抽象隔离,要更具具体业务判断.
封闭原则: java 类的封装是这一原则的体现.同时项目完成后,如果业务需求发生变动,需要通过增加新代码来增加改进,而不是对现有代码改写.
个人理解这部分,我也只是纸上谈兵.没有开发项目和改需求的经验,很难运用这两个原则.