在本篇文章中,有关于UML类图的基本知识,如果有还不太清楚的可以参照:
在我们实例化对象时,第一个想到的就是new对象,没有房子,new一个,没有女朋友,new一个甚至好多个。new对象就是和类之间建立了耦合关系,如果有很多的对象,那么类与对象间就形成了强耦合,灵活性就变差了,所以,一般我们在开发过程中都是面向"接口"编程的,通过多态,可以与任何新类实现该接口。但是,同样,代码量太大,就搞不定了!那么除了new就再没有其他的办法了吗?这就涉及到了设计模式的设计:
用户在测试类中指定要创建的类型:
大家先看类图:
说明:Pizza类为抽象类,然后 CheesePizza和ClamPizza继承Pizza类并且重写prepare方法,然后,在SimpleFactory简单工厂中根据类型来创建指定的Pizza,然后在PizzStore中组合SimpleFactory,用户要什么Pizza,就在PizzaStore中告诉,然后让SimpleFactory造一个指定类型的,它本身并不用关心要什么类型的Pizza。不论什么Pizza最后都要bake,cut,box操作,在SimpleFactory创建完Pizza后,PizzaStore就执行bake,cut,box。当然会有同学问,如果再增加一个种类的Pizza呢,这时我们就可以在SimpleFactory中添加就搞定了,做到了“对扩展开放,对修改关闭”,满口了ocp原则!下面来看具体的实现过程
- Pizza
public abstract class Pizza {
private String name;
public abstract void prepare();
public void bake(){
System.out.println(name+ " "+ "backing");
}
public void cut(){
System.out.println(name+ " "+ "cutting");
}
public void box(){
System.out.println(name+ " "+ "boxing");
}
public void setName(String name) {
this.name = name;
}
}
- ClamPizza
public class ClamPizza extends Pizza {
@Override
public void prepare() {
System.out.println("加入ClamPizza调料");
}
}
- CheesePizza
public class CheesePizza extends Pizza {
@Override
public void prepare() {
System.out.println("加入CheesePizza调料");
}
}
- SimpleFactory
public class SimpleFactory {
public Pizza createPizza(String type){
Pizza pizza = null;
if (type.equals("Clam")){
pizza = new ClamPizza();
pizza.setName(type);
}else if (type.equals("Cheese")){
pizza = new CheesePizza();
pizza.setName(type);
}
return pizza;
}
}
- PizzaStore
public class PizzaStore {
SimpleFactory simpleFactory;
public void setSimpleFactory(SimpleFactory simpleFactory) {
this.simpleFactory = simpleFactory;
}
public Pizza orderPizza(String type, SimpleFactory simpleFactory){
Pizza pizza;
pizza = simpleFactory.createPizza(type);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
- TestPizza
public class TestPizza {
public static void main(String[] args) {
//新建一个PizzaStore用来卖Pizza
PizzaStore pizzaStore = new PizzaStore();
//传入要买的类型,并且要有一个工厂
pizzaStore.orderPizza("Clam",new SimpleFactory());
}
}
- 测试结果
用户在控制台动态输入要创建的类型:
1)有两种披萨:希腊披萨(greek),奶酪披萨(cheese)
2)批萨的制作有bak,cut,box;
3)给定一个类型,创建披萨的流程
- Pizza
//定义一个抽象的披萨类
public abstract class Pizza {
//抽象方法
public abstract void prepare();
//制做的工艺
public void bake() {
System.out.println("baking;");
}
public void cut() {
System.out.println("cuting;");
}
public void box() {
System.out.println("boxing;");
}
}
- CheesePizza2
public class CheesePizza2 extends Pizza {
@Override
public void prepare() {
System.out.println("给奶酪披萨准备原材料");
}
}
- GreekPizza2
public class GreekPizza2 extends Pizza{
@Override
public void prepare() {
System.out.println("给希腊披萨准备原材料");
}
}
- orderPizza2
public class orderPizza2 {
Pizza pizza = null;
public Pizza orderPizza(String orderType){
if (orderType.equals("greek")){
pizza = new GreekPizza2();
}else if (orderType.equals("cheese")){
pizza = new CheesePizza2();
}
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
return pizza;
}
}
- PizzaStore
public class PizzaStore {
public static void main(String[] args) {
orderPizza2 orderPizza2 = new orderPizza2();
orderPizza2.orderPizza("greek");
orderPizza2.orderPizza("cheese");
}
}
- 测试
- 还有类图
虽然我们的功能实现了,但是当我们再加一个种类的披萨时,就要在orderPizza2 里面添加,如果能把orderPizza2 里面的根据名称创建哪种披萨的方法抽离出去,新建一个方法,专门用来创建对象,然后在orderPizza2内部聚合这个新的方法,这样做,就会对扩展开放,对修改关闭,从而满足了ocp原则,说干就干!
- Pizza
public abstract class Pizza {
public abstract void prepare();
public void bake() {
System.out.println("baking;");
}
public void cut() {
System.out.println("cuting;");
}
public void box() {
System.out.println("boxing;");
}
}
- CheesePizza2
public class CheesePizza2 extends Pizza {
@Override
public void prepare() {
System.out.println("经制做奶酪披萨准备原材料");
}
}
- GreekPizza2
public class GreekPizza2 extends Pizza{
@Override
public void prepare() {
System.out.println("给希腊披萨准备原材料");
}
}
- SimpleFactory2
public class SimpleFactory2 {
public Pizza createPizza(String orderType){
Pizza pizza = null;
if (orderType.equals("greek")){
pizza = new GreekPizza2();
}else if (orderType.equals("cheese")){
pizza = new CheesePizza2();
}
return pizza;
}
}
- OrderPizza2
//定义一个生成厂商,对传入的某种披萨进行prepare,bake,cut,box操作
public class orderPizza2 {
SimpleFactory2 simpleFactory2;
Pizza pizza = null;
public orderPizza2(SimpleFactory2 simpleFactory2) {
setSimpleFactory2(simpleFactory2);
}
public void setSimpleFactory2(SimpleFactory2 simpleFactory2) {
this.simpleFactory2 = simpleFactory2;
//获取披萨的类型是什么
String orderType = " ";
orderType = getype();
pizza = simpleFactory2.createPizza(orderType);
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
}
//写一个方法,可以获取客户端希望订购的披萨种类
private String getype(){
try {
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
System.out.println("input Pizza type:");
String str = strin.readLine();
return str;
}catch (IOException e){
e.printStackTrace();
return "";
}
}
}
- PizzaStore
public class PizzaStore {
public static void main(String[] args) {
new orderPizza2(new SimpleFactory2());
}
}
- 结果
- 类图表示
在实例化批萨时,我们使用了一个工厂来根据类型创建批萨,在OrderPizza2里面再来实现prepare,bake,cut,box操作,如果要增加一个新的种类的批萨,只需要在工厂类中加入方法,其他的代码都不用变动,这就实现了简化 代码的目的!
在本篇文章中,有关于UML类图的基本知识,如果有还不太清楚的可以参照:
如果大家觉得写的有问题可以在评论区留言!