每周总结10
工厂模式小结
一、简单工厂的创建
1.工厂,简单工厂
//工厂类是一个接口or抽象类。
招待员?是一个具体的类,不是接口也不是抽象类。具有一个重要的create()方法(常是静态,故又称静态工厂),
利用if or switch创建想要的产品并返回。
大致分为3个包(有一个没有单独建立包(顾客))4个类
工厂包,一个抽象工厂类,有一个行为方法。
package com.XGX.PetShop;
public abstract class PetShop {
public abstract void sell();//只有接口里面可以省略,抽象类这种还是要写public abstract的格式。
}
然后是产品包,产品类,继承工厂并且重写产行为方法。
package com.XGX.Pet;
import com.XGX.PetShop.*;
public class Bird extends PetShop{
@Override
public void sell(){
System.out.println("客人要买小鸟,飞来一只小鸟在唱歌。");
}
}
package com.XGX.Pet;
import com.XGX.PetShop.*;
public class Dog extends PetShop{
@Override
public void sell(){
System.out.println("客人要买小狗,跑来一只小狗在汪汪。");
}
}
package com.XGX.Pet;
import com.XGX.PetShop.*;
public class Fish extends PetShop{
@Override
public void sell(){
System.out.println("客人要买小鱼,游来一只小鱼在吐泡泡。");
}
}
然后是员工类,来根据需求返回产品对象,实现传递点菜,建立工厂(产品)和顾客之间的联系,避免
package com.XGX.Worker;
import com.XGX.PetShop.*;
import com.XGX.Pet.*;
public class Worker {
//用 final static 创建常量,记得public 和 全大写
public final static int BIRD = 1;//小鸟
public final static int DOG = 2;//小狗
public final static int FISH = 3;//小鱼
//创建常量代称,给产品编号,方便识别和提供
//这样方便改和增加代称?
//写一个静态的提供返回产品对象的创造方法
public static PetShop getPet(int Type){//有参方法,创造对应的宠物产品对象
switch(Type){
case BIRD:
return new Bird();
case DOG:
return new Dog();
default: FISH://这里可以用default,必须要用default,不然有可能情况全部落空,就没有返回值了,不写default的话
//就一定要在switch的外面再写一个return 语句。
return new Fish();
}
}
}
然后是顾客类,来测试,测试类,来运行享受工厂的服务。
因为要继承和重写之类的,肯定要记得导包,不然无法具备那些方法和识别类名等关键字,无法建立联系。
package com.XGX;
import java.util.*;
import com.XGX.PetShop.*;
import com.XGX.Pet.*;
import com.XGX.Worker.*;
public class Customer {
public static void main(String[] args){
//System.out.println("欢迎光临宠物店,请问您想要买什么宠物,输入1,买小鸟,输入2,买小狗,输入3买小鱼");
//Scanner in = new Scanner(System.in);
//int a = in.nextInt();
//PetShop petShop = Worker.getPet(BIRD);//这里识别不了BIRD,即便已经导入了对应的包,这个常量好像必须得靠类名来调用
PetShop petShop = Worker.getPet(Worker.BIRD);
PetShop p2 = Worker.getPet(Worker.DOG);
PetShop p3 = Worker.getPet(Worker.FISH);
//最后用创建出来的产品对象调用行为方法,完成运行,达成目的,实现预设结果。
petShop.sell();
p2.sell();
p3.sell();
}
}
//运行结果
客人要买小鸟,飞来一只小鸟在唱歌。
客人要买小狗,跑来一只小狗在汪汪。
客人要买小鱼,游来一只小鱼在吐泡泡。
顾客类直接写在包下面,和其他三个包一级,不用单独建立包了。
顾客这个类就要导入所有的包,都要用到。
顾客类中的main(String[] args)方法
工厂类名 a = 员工.create(员工.产品);
这样,创建了一个父类型引用,指向子类型对象,可以实现多态的调用子类型方法。
这里不用工厂这一众多产品的父类做引用而用子类产品or非父类的类做引用类型的话就兼容不了众多子类。
这里通过create()方法返回了产品对象,可以直接去调用方法,完成目标。
这里的create()也就相当于构造方法了,都是创建对象只不过不是创建自己那个类的类型。
最后用创建出来的产品对象调用行为方法,完成运行,达成目的,实现预设结果。
2.工厂方法模式
又称工厂,多态工厂和虚拟构造器模式。
通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
主要作用是,将类的实例化(具体产品的创建)推迟到工厂类的子类(具体工厂)中完成。
由子类来决定应该实例化(创建)哪一个类。
解决了简单工厂模式的缺点。
添加新产品只需要添加新的工厂子类。具体的工厂子类去继承接口。
推迟,拖延了一下,就符合开闭原则了,适合于添加,不必要改动。
3.抽象工厂
抽象产品(父类
具体产品
抽象工厂(父类
具体工厂
利用了多态,直接用父类型引用指向子类型对象,都可以调用子类的方法,实现多种表现形态。
抽象工厂,非常适合解决多个维度的组合产品构造问题。
即有多重的产品分类。
好像用抽象类和接口都是可以的。
package com.XGX.Factory;
import com.XGX.Bird.*;
import com.XGX.Pet.*;
public abstract class Factory {
public static Pet create(){
return new Bird();
};//抽象不了就别抽!,抽象的东西不能用static修饰
}
package com.XGX.Pet;
public abstract class Pet {
public abstract void show();
}
package com.XGX.Cat;
import com.XGX.Pet.*;
public class Cat extends Pet{
public Cat(){}
public void show(){
}
}
package com.XGX.Bird;
import com.XGX.Pet.*;
public class Bird extends Pet{
public Bird(){}
public void show(){
}
}
package com.XGX.Acat;
import com.XGX.Cat.*;
public class Acat extends Cat{
public Acat(){}
public void show(){
System.out.println("跑来了一只小Acat.");
}
}
package com.XGX.Bcat;
import com.XGX.Cat.*;
public class Bcat extends Cat{
public Bcat(){}
public void show(){
System.out.println("跑来了一只小Bcat.");
}
}
package com.XGX.YingWu;
import com.XGX.Bird.*;
public class YingWu extends Bird{
public YingWu(){}
public void show(){
System.out.println("飞来了一只小YingWu.");
}
}
package com.XGX.BaGe;
import com.XGX.Bird.*;
public class BaGe extends Bird{
public BaGe(){}
public void show(){
System.out.println("飞来了一只小BaGe.");
}
}
package com.XGX.CatF;
import com.XGX.Bird.Bird;
import com.XGX.Factory.*;
import com.XGX.Acat.*;
import com.XGX.Bcat.*;
import com.XGX.Cat.*;
import java.util.Scanner;
public class CatF extends Factory{
public CatF(){}
public static Cat create(){
System.out.println("我们这里有Acat和Bcat两种猫,请输入您想要的猫。");
Scanner in = new Scanner(System.in);
String a = in.nextLine();
if(a.equals("Acat")){
return new Acat();
}
else if(a.equals("Bcat")){
return new Bcat();
}
else {
System.out.println("对不起,本小店没有这种宠物。。。");
return new Cat();
}
}
}
package com.XGX.BirdF;
import com.XGX.Bird.*;
import com.XGX.Factory.*;
import java.util.*;//Scanner用
import com.XGX.YingWu.*;
import com.XGX.BaGe.*;
public class BirdF extends Factory {
public BirdF(){}
public static Bird create(){
System.out.println("我们这里有YingWu和BaGe两种鸟,请输入您想要的鸟。");
Scanner in = new Scanner(System.in);
String a = in.nextLine();
if(a.equals("YingWu")){
return new YingWu();
}
else if(a.equals("BaGe")){
return new BaGe();
}
else {
System.out.println("对不起,本小店没有这种宠物。。。");
return new Bird();
}
}
}
package com.XGX.Test;
import java.util.*;
import com.XGX.Pet.*;
import com.XGX.CatF.*;
import com.XGX.BirdF.*;
public class Test {
public static void main(String[] args){
System.out.println("欢迎光临宠物店,这里有小猫和小鸟,请问客人需要哪一种?");
System.out.println("如果需要小猫请输入'Cat'。需要小鸟请输入'Bird'.");
Scanner in = new Scanner(System.in);
String a = in.nextLine();
if(a.equals("Cat")){
//Pet p1 = CatF.create(String a);//这里是直接传形参,不用声明了。
Pet p1 = CatF.create();
p1.show();
}
else if(a.equals("Bird")){
Pet p1 = BirdF.create();
p1.show();
}
else{
System.out.println("对不起,本小店没有这种宠物。。。");
}
}
}
///测试运行
欢迎光临宠物店,这里有小猫和小鸟,请问客人需要哪一种?
如果需要小猫请输入'Cat'。需要小鸟请输入'Bird'.
Cat
我们这里有Acat和Bcat两种猫,请输入您想要的猫。
Acat
跑来了一只小Acat.
欢迎光临宠物店,这里有小猫和小鸟,请问客人需要哪一种?
如果需要小猫请输入'Cat'。需要小鸟请输入'Bird'.
Bird
我们这里有YingWu和BaGe两种鸟,请输入您想要的鸟。
YingWu
飞来了一只小YingWu.
欢迎光临宠物店,这里有小猫和小鸟,请问客人需要哪一种?
如果需要小猫请输入'Cat'。需要小鸟请输入'Bird'.
Rubbish
对不起,本小店没有这种宠物。。。