借鉴 :《大话数据结构》 http://www.cnblogs.com/cj723/
活字印刷--面向对象
活字印刷,即当需要改变部分字的时候,不需要整个刻板全部重新刻,解耦。
- 可维护
- 要改,只需更改要改之字
- 可复用
- 这些字并非这次用完就无用,完全可以后来的印刷中重复使用
- 可扩展
- 若需要在已有内容里加字,只需要另刻字加入即可
- 灵活性好
- 子的排版可能是竖排也可能是横排,需求改变时只需要将活字移动就克做到满足排列需求
所以需要通过 封装、继承、多态把程序的耦合度降到最低
- 业务的封装
- 将业务逻辑与界面逻辑分开,让他们之间的耦合度下降
- 比如一个Windows计算器,将计算和显示分开
- Operation运算类
- 加减乘除功能具体实现
- 客户端类
- 输入界面的UI
- Operation运算类
- 只增加一个功能,不影响计算器原有的功能代码发生改变--将加减乘除等运算分离,修改其中一个不影响另外的几个
- Operation类
- set 与 get 方法
- 虚方法:GetResult()用于得到结果
- 加减乘除类 继承 Operation类
- 加减乘除功能具体实现
- 对于每一个功能重写GetResult()方法
- 加减乘除功能具体实现
- 客户端类
- Operation类
现在的问题是:如何去实例话一个对象
1.简单工厂模式--"switch-case"--类创建型模式

专门定义一个类用来负责创建其他类的实例,被创建的实例通常都具有共同的父类
public class OperationFactory {
public static BaseOperation createOperation(String operate) {
int sum = 0;
switch (operate) {
case "+":
sum=new OperationAdd();
break;
case "-":
sum=new OperationSub();
break;
case "*":
sum=new OperationMul();
break;
case "/":
sum=new OperationDiv();
break;
}
return sum ;
}
}
- 优点
- 工厂类是整个模式的关键,包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象
- 缺点
- 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
- 意义
- 通过使用工厂类,外界可以从直接创建具体产品对象转换为直接使用对象就可以了,而不必管这些对象是如何创建及如何组织的,明确了各自的职责和权利,有利于整个软件体系结构的优化
相关借鉴: https://www.jianshu.com/p/3f824a91d73b https://juejin.cn/post/6844903501240205320
继续阅读的知识点补充与温故:
1.抽象--abstract
Animal类根本就不可能实例化,一只猫长什么样子可以想象,但是实例化一个动物,那么动物长什么样?所以动物是一个抽象的名词,没有具体对象与之对应
【抽象类的注意事项】
- 抽象类不能实例化
- Animal实例化没有意义
- 抽象方法是 必须 被子类重写 的方法
- 如果类中包含抽象方法,那么累就必须定义为抽象类,不论是否还包含其他一般的方法
抽象类应该拥有尽可能多的共同代码,拥有尽可能少的数据
设计一个抽象类时,一定是用来继承的

如果牛、羊、狗、猫、猴是最后一级,那么他们就是具体类,
但如果还有更下面一级的金丝猴继承于猴,哈巴狗继承于狗,
那就需要考虑把猫和狗改为抽象类的了
2.开放-封闭原则--多扩展,少修改--面对对象设计的核心所在
精髓:面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码
- 对于拓展是开放的
- 对于更改是封闭的
2.工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类
工厂模式使一个类的实例化延迟到其子类

简单工厂模式 和 工厂模式 的 对比例子--雷锋工厂
//定义一个雷锋类
public class LeiFeng {
public void sweep(){
System.out.println("扫地");
}
public void wash(){
System.out.println("洗衣");
}
public void cook(){
System.out.println("做饭");
}
}
//学雷锋的大学生类,继承雷锋
public class Undergraduate extends LeiFeng
{
}
//客户端代码
public class Main
{
public static void main(String[] args)
{
LeiFeng xueleifeng = new Undergraduate();
xueleifeng.buyRice();
xueleifeng.sweep();
xueleifeng.wash();
}
}
- 现在假设有三个人要去代替他做这些事,那就应该实例化三个学雷锋的大学生对象了
LeiFeng student1 = new Undergraduate();
student1.buyRice();
LeiFeng student2 = new Undergraduate();
student2.sweep();
LeiFeng student3 = new Undergraduate();
student3.wash();
- 然而不仅仅有大学生去帮助老人,还有“社区志愿者”也会参与其中,那么这样的写法就非常不合适了,因为我们需要更改多个实例化的地方,所以还需要增加一个继承“雷锋”的类 --“社区志愿者”类
1.简单工厂模式
//社区志愿者
public class Volunteer extends LeiFeng
{
}
//简单工厂类
public class SimpleFactory
{
public static LeiFeng createLeiFeng(String type)
{
LeiFeng result = null;
if ("学雷锋的大学生".equals(type))
{
result = new Undergraduate();
}
else if ("社区志愿者".equals(type))
{
result = new Volunteer();
}
return result;
}
}
//客户端代码,如果要换,就只需要换“学雷锋的大学生”为“社区志愿者”
LeiFeng studentA = SimpleFactory.createLeiFeng("学雷锋的大学生");
studentA.buyRice();
LeiFeng studentB = SimpleFactory.createLeiFeng("学雷锋的大学生");
studentB.sweep();
LeiFeng studentC = SimpleFactory.createLeiFeng("学雷锋的大学生");
studentC.wash();
2.工厂模式
//雷锋工厂
public interface IFactory
{
LeiFeng createLeiFeng();
}
//学雷锋的大学生工厂
public class UndergraduateFactory implements IFactory
{
public LeiFeng createLeiFeng()
{
return new Undergraduate();
}
}
//社区志愿者工厂
public class VolunteerFactory implements IFactory
{
public LeiFeng createLeiFeng()
{
return new Volunteer();
}
}
//客户端代码
public class Main
{
public static void main(String[] args)
{
//要换成“社区志愿者”修改这里就可以了
//只需要修改一处就可以了,这是最佳的做法
IFactory factory = new UndergraduateFactory();
LeiFeng student = factory.createLeiFeng();
student.buyRice();
student.sweep();
student.wash();
}
}
- 总结:
- 他们都是集中封装了对象的创建,使得要更换对象时候,不需要做大的改动就能实现,降低了客户端与产品对象的耦合
- 工厂模式使简单工厂模式的进一步抽象和推广
3.策略模式--算法独立于使用它的客户而变化
- Context: 环境类
- Strategy: 抽象策略类
- Strategy: 抽象策略类
它定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化,不会影响使用算法的客户。
参考:http://hjxandhmr.github.io/2016/06/10/DesignPattern-Strategy/