抽象工厂模式
1. 设计模式之抽象工厂模式
在学习抽象工厂模式前要先了解一下工厂模式,而抽象工厂模式主要就是为了弥补工厂模式的缺点的,抽象~遵循了开闭原则
设计原则之开闭原则 (Open Close Principle,缩写OCP)
类、模块、函数等对于拓展是开放的,但是对于修改是封闭的,当软件需要变化时,应该尽量通过拓展的方式来实现变化,而不是通过修改已有的代码来实现。(接口)
附上链接
- 简单工厂模式中没有抽象,直接创建一一对应就不符合开闭原则
- 而工厂模式已经引入了抽象,工厂方法模式组成:
1)抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在java中它由抽象类或者接口来实现。 2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。 3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在java中一般有抽象类或者接口来实现。 4)具体产品角色:具体工厂角色所创建的对象就是此角色的实例。在java中由具体的类来实现。 工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有 的代码。可以看出工厂角色的结构也是符合开闭原则的!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
381. abstract class BMW {
2. public BMW(){
4. }
5. }
6. public class BMW320 extends BMW {
7. public BMW320() {
8. System.out.println("制造-->BMW320");
9. }
10. }
11. public class BMW523 extends BMW{
12. public BMW523(){
13. System.out.println("制造-->BMW523");
14. }
15. }
创建工厂类:
1. interface FactoryBMW {
2. BMW createBMW();
3. }
5. public class FactoryBMW320 implements FactoryBMW{
7. @Override
8. public BMW320 createBMW() {
10. return new BMW320();
11. }
13. }
14. public class FactoryBMW523 implements FactoryBMW {
15. @Override
16. public BMW523 createBMW() {
18. return new BMW523();
19. }
20. }
- 最后是抽象工厂模式,他工厂模式有些相似,但是他的特点:
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象
。
比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。参考https://blog.csdn.net/jason0539/article/details/449767751
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63//发动机以及型号
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
创建工厂类:
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
2.android设计模式之策略模式
策略模式跟上面工厂模式也有相似,都是利用调用方法是传入不同的接口对象
- 一般的做法是在一个类里写不同的方法,然后根据实际情况用一连串的if-else或switch来选择对应的方法。这种方法多了后,这个类会变得臃肿,难以修改。(类似于简单工厂模式)
- 所以如果把不同的策略抽象出来,提供
一个统一的接口
,为每一个策略写一个实现类,这样客户端就能通过调用接口的不同的实现类来动态替换策略。这就是策略模式
1 | //定义一类的策略接口 |
更好的代码参考:https://blog.csdn.net/qq_25806863/article/details/68623134
分治法
算法之 分治法 Divide and Conquer
分治法:
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
使用条件
分治法所能解决的问题一般具有以下几个特征:
- 分解:将大问题的分解成小问题,是这个算法的核心。也是使用分治法的效率保证,如果分解不合理。那么反而会弄巧成拙。
- 解决:解决问题,便是分解之后的小问题。他们的解决步骤是相同,至少是相似的。所以,分治法中经常用到递归,就是基于这样的目的。
- 合并:前面那么麻烦的两步,最终的目的仍然是为了解决这个问题。所以需要将分解问题得到的解,合并成最终需要的终极答案,便是这个算法的结束过程。譬如,你使用递归的时候,也需要最后退出的条件。分治法结束条件,就是合并步骤的结束。
所以可以看出分治法与递归联系紧密,时常一起出现,但也有区别,对于分治法,一定要注意会有和这一步,但有时在递归的过程中自动出现和这一步,不用太区分。要理解分治的思想。
主要应用
- 二分搜索:
- 快速排序:
- 分:找到一个基准数;把小于这个数的数都放到左边,把大于这个数的数都放到右边;
- 解:递归快排
- 组合:因为当”求解”步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,”组合”步骤无须做什么,可看作是空操作
- 大整数乘法:
leetcode题目分析:
1 分解:这个数组只能出现在三个位置:从中间分,要么完全在左边,要么完全在右边,要么穿过中间,所以分三部分求最大
2 求解:如果在左边或右边继续分,最后只剩一个数返回,对于穿过中间的,分成两部分求最大,每次都如此。
3 组合:每次返回左边,右边,中间这三个中最大的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26class Solution {
public int maxSubArray(int[] nums) {
return findMax(nums,0,nums.length-1);
}
public static int findMax(int []num,int left,int right){
if (left>=right)return num[left];
int mid=(left+right)/2;
//寻找左边最大
int lmax=findMax(num,left,mid-1);
//寻找右边最大
int rmax=findMax(num,mid+1,right);
//寻找中间最大,并分成两部分,找从中间左边连续最大,中间到右边连续最大,最后加起来
int mmax=num[mid],t=mmax;
for (int i=mid-1;i>=left;i--){
t+=num[i];
mmax=Math.max(mmax,t);
}
t=mmax;
for (int i=mid+1; i<=right; i++){
t+=num[i];
mmax=Math.max(mmax,t);
}
//合并
return Math.max(mmax,Math.max(lmax,rmax));
}
}1 分:每次遇到符号,分成前后两部分,并记录该符号
2 解:让左边的运算的所有结果去分别加后边运算的所有结果,分解直到只有两个数子,让他们运算,
3 组合:每次的结果都计入数组返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> res = new ArrayList<Integer>();
for (int i=0; i<input.length(); i++) {
char ch = input.charAt(i);
if (ch == '+' || ch == '-' || ch == '*') {
List<Integer> left = diffWaysToCompute(input.substring(0,i));
List<Integer> right = diffWaysToCompute(input.substring(i+1,input.length()));
for (int l : left) {
for (int r : right) {
switch(ch) {
case '+' :
res.add(l+r);
break;
case '-' :
res.add(l-r);
break;
case '*' :
res.add(l*r);
break;
}
}
}
}
}
if (res.size() == 0) res.add(Integer.valueOf(input));
return res;
}
}
- 215. Kth Largest Element in an Array:
这道题就只要先快速排序一下就可以找到了
java 泛型
泛型,一个孤独的守门者
关于泛型的具体细节这篇博客我觉得讲得十分详细,所以我分享一下我学习中的一些难点与体会。
1.学习泛型要先掌握java的类型转换机制java引用数据类型转换,由于继承,java自然的向上转换,父类转换为子类需要特定条件。
2.作用:泛型,就是参数类型化,把一个类型作为参数传递进去,而把他成为守门人,很好的形容了泛型的功能。在没有泛型之前,一般都是用继承,object这个基类来实现但是这样不管加入任何类型都可以,所以需要泛型这个守门人,检测传入的类型,可以在编译阶段查出错误。
1 | List arrayList = new ArrayList(); |
崩溃
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
1 | List<String> arrayList = new ArrayList<String>(); |
3.类型擦出,理解反省的这个特性才能完全掌握泛型。
泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,。泛型全部转换为object,与普通类没什么区别(如有类型限定则转换为限定类型)所以说,泛型是一个守门人,在编译的时候提醒你传入什么类型,相应的,我们也可以利用反射,我们绕过编译器去调用 add 方法
4.通配符?
Java 泛型通配符和类型限定
关于上限与下限的读取使用说明
我认为很好的例子
1 |
|
Hello World
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick Start
Create a new post
1 | $ hexo new "My New Post" |
More info: Writing
Run server
1 | $ hexo server |
More info: Server
Generate static files
1 | $ hexo generate |
More info: Generating
Deploy to remote sites
1 | $ hexo deploy |
More info: Deployment