Software design pattern and architecture [collection of experimental reports]

Four experiments (two class hours): strategy mode, decorator mode, abstract factory mode, command mode [no GUI interface, only the simplest requirements]

If this article is useful to you, remember to like it! The following are textbooks & reference books 

Strategy Pattern

       The strategy mode defines a family of algorithms, which are encapsulated separately so that they can be replaced with each other. This mode makes the algorithm changes independent of the customers who use the algorithm. On the basis of familiarity with the relevant theoretical knowledge of the strategy mode, use the strategy mode to implement a small game.

1. Basic requirements

       To implement a small game using strategy mode, the requirements are as follows:

  1. There are three characters in the game: monk, chivalrous girl, ninja;
  2. Each character has health and mana, but each character is different.
  3. The appearance of each character is different.
  4. Each character has magic attack and physical attack;
  5. There are three types of physical attacks: knife, sword, and hand;
  6. There are also three types of magic attacks: fire magic, gold magic, and water magic;

       Each character can dynamically change the physical and magical attack methods, and can also dynamically select the attack method.

       The author recommends to refer to https://blog.csdn.net/qq_42685588/article/details/103576562

2. Experimental content

       1. Design and draw the class diagram of the program;

       2. Use Java language to write code in accordance with the designed class diagram and implement the program;

       3. In addition to the implementation of core pattern-related classes, a test environment is provided. According to the level of difficulty, they are:

              a) Console program, Client hard-coded initialization mode and test environment, and text output of running results;

              b) Console program, Client initializes the test environment, calculates according to user input, and outputs text output of running results;

              c) Design and implement the user UI, the Client initializes the test environment, and outputs the text output of the running result according to the user's input on the UI control;

Three, experimental tips

       1. The structure and components of the strategy pattern

  • Strategy: Define all public interfaces that support algorithms. Context uses this interface to call an algorithm defined by a ConcreteStrategy;
  • ConcreteStrategy: implement a specific algorithm with Strategy interface;
  • Context: Use a ConcreteStrategy object to configure, maintain a reference to the Strategy object, and define an interface to allow Strategy to access its data;

       2. Strategy mode code hint [ from the book "Head First Design Pattern" ]

       SimUDuck example: understand the behavior of duck as "a set of behaviors" and use the "a family of algorithms" of the strategy pattern to implement it.

        Duck base class

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;
 
	public Duck() {
	}
 
	public void setFlyBehavior (FlyBehavior fb) {
		flyBehavior = fb;
	}
 
	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
 
	abstract void display();
 
	public void performFly() {
		flyBehavior.fly();
	}
 
	public void performQuack() {
		quackBehavior.quack();
	}
 
	public void swim() {
		System.out.println("All ducks float, even decoys!");
	}
}

        FlyBehavior and QuackBehavior interface

public interface QuackBehavior {
	public void quack();
}

public interface FlyBehavior {
	public void fly();
}

       FlyWithWings specific behavior

public class FlyWithWings implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying!!");
	}
}

        MiniDuckSimulator test environment

public class MiniDuckSimulator {
 
	public static void main(String[] args) {
 
		MallardDuck	mallard = new MallardDuck();
		RubberDuck rubberDuckie = new RubberDuck();
		DecoyDuck decoy = new DecoyDuck();

		ModelDuck model = new ModelDuck();

		mallard.performQuack();
		rubberDuckie.performQuack();
		decoy.performQuack();
   
		model.performFly();	
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();
	}
}

 4. Experimental principle (algorithm or diagram)

                                                                               Figure 1 Class diagram of the strategy pattern 

Five, the source code

Role (base class)

public abstract class Role {
	Magic magic;
	Physics physics;
	
	public Role(Magic magic, Physics physics) {
		setMagic(magic);
		setPhysics(physics);
	};
	
	public abstract void display();
	
	public void performMagic() {
		magic.magicAttack();
	}
	
	public void performPhysics() {
		physics.physicsAttack();
	}
	
	public void setMagic(Magic magic) {
		this.magic = magic;
	}
	
	public void setPhysics(Physics physics) {
		this.physics = physics;
	}
}

Monk, Heroine, Ninja (subcategory)

public class Monk extends Role {
	public Monk(Magic magic, Physics physics) {
		super(magic, physics);
	}

	@Override
	public void display() {
		System.out.println("我外貌像个和尚");
	}
}
public class Heroine extends Role {
	public Heroine(Magic magic, Physics physics) {
		super(magic, physics);
	}

	@Override
	public void display() {
		System.out.println("我外貌像个侠女");
	}
}
public class Ninja extends Role {
	public Ninja(Magic magic, Physics physics) {
		super(magic, physics);
	}

	@Override
	public void display() {
		System.out.println("我外貌像个忍者");
	}
}

Magic interface 

public interface Magic {
	public void magicAttack() ;
}

Class that implements Magic

public class MagicFire implements Magic {
	@Override
	public void magicAttack() {
		System.out.println("正在使用火系魔法攻击");
	}
}
public class MagicGold implements Magic {
	@Override
	public void magicAttack() {
		System.out.println("正在使用金系魔法攻击");
	}
}
public class MagicWater implements Magic {
	@Override
	public void magicAttack() {
		System.out.println("正在使用水系魔法攻击");
	}
}

Physics interface

public interface Physics {
	public void physicsAttack() ;
}

Classes that implement Physics

public class PhysicsHand implements Physics {
	@Override
	public void physicsAttack() {
		System.out.println("正在使用手进行物理攻击");
	}
}
public class PhysicsKnife implements Physics {
	@Override
	public void physicsAttack() {
		System.out.println("正在使用刀进行物理攻击");
	}
}
public class PhysicsSword  implements Physics {
	@Override
	public void physicsAttack() {
		System.out.println("正在使用剑进行物理攻击");
	}
}

Test class

public class Test {
	public static void main(String[] args) {
		Monk monk = new Monk(new MagicGold(), new PhysicsHand());
		monk.display();
		monk.performPhysics();
		monk.performMagic();
		
		Heroine heroine  =new Heroine(new MagicWater(), new PhysicsSword());
		heroine.display();
		heroine.performPhysics();
		heroine.performMagic();
		
		Ninja ninja = new Ninja(new MagicFire(), new PhysicsSword());
		ninja.display();
		ninja.performPhysics();
		ninja.performMagic();
	}
}

 Six, operation results

 Decorator Pattern

        The decorator pattern dynamically attaches responsibilities to the object. To extend the functionality, decorators provide a more flexible alternative than inheritance. On the basis of familiarity with the relevant theoretical knowledge of the decorator mode, the installer mode is used to realize the checkout applet of the rice noodle shop.

1. Basic requirements

        To use the decorator mode to realize the checkout procedure of the rice noodle shop , the requirements are as follows:

  1. There are three types of rice noodles, dry pulp, physalis and water rice noodles.
  2. There are three kinds of ingredients, tofu, eggs, beef, and there will be more in the future.
  3. Customers suspiciously want various rice noodles with various ingredients. The ingredients can be added with the same type and multiple portions, or different types and multiple portions.

2. Experimental content

        1. Design and draw the class diagram of the program;

        2. Use Java language to write code in accordance with the designed class diagram and implement the program;

        3. In addition to the implementation of core pattern-related classes, a test environment is provided. According to the level of difficulty, they are:

              a) Console program, Client hard-coded initialization mode and test environment, and text output of running results;

              b) Console program, Client initializes the test environment, calculates according to user input, and outputs text output of running results;

              c) Design and implement the user UI, the Client initializes the test environment, and outputs the text output of the running result according to the user's input on the UI control;

Three, experimental tips

        1. The structure and components of the decorator pattern

  • Component: object interface, which can dynamically add responsibilities to the object;
  • Concrete Component: specific object;
  • Decorator: maintain a pointer to the Component object and define an interface consistent with the Component interface;
  • ConcreteDecorator: add responsibilities to the component;
  • Decorator forwards the request to its Component object, and may perform some additional actions before and after forwarding the request;

        2. Decorator mode code hint

        Example of Starbuzz: Taking beverage as the main body, and then "decorating" the beverage with seasoning at runtime.

        Beverage base class

public abstract class Beverage {
	String description = "Unknown Beverage";
  
	public String getDescription() {
		return description;
	}
 
	public abstract double cost();
}

        HouseBlend specific beverages

public class HouseBlend extends Beverage {
	public HouseBlend() {
		description = "House Blend Coffee";
	}
 
	public double cost() {
		return .89;
	}
}

        CondimentDecorator base class

public abstract class CondimentDecorator extends Beverage {
	public abstract String getDescription();
}

        Soy specific seasonings

public class Soy extends CondimentDecorator {
	Beverage beverage;

	public Soy(Beverage beverage) {
		this.beverage = beverage;
	}

	public String getDescription() {
		return beverage.getDescription() + ", Soy";
	}

	public double cost() {
		return .15 + beverage.cost();
	}
}

        StarbuzzCoffee test environment

public class StarbuzzCoffee {
 
	public static void main(String args[]) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription() + " $" + beverage.cost());
 
		Beverage beverage2 = new DarkRoast();
		beverage2 = new Mocha(beverage2);
		beverage2 = new Mocha(beverage2);
		beverage2 = new Whip(beverage2);
		System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
 
		Beverage beverage3 = new HouseBlend();
		beverage3 = new Soy(beverage3);
		beverage3 = new Mocha(beverage3);
		beverage3 = new Whip(beverage3);
		System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
	}
}

4. Experimental principle (algorithm or diagram)

 Five, source code

Noodles base class

public abstract class Noodles {
	private String description = null;
	
	public String getDescription() {
	 	return description;
	}

	public void setDescription(String description) {
	 	this.description = description;
	}

	public abstract double cost();
}

 Inherit the Noodles class

public class NoodlesAcid extends Noodles {
	public NoodlesAcid() {
    	String description="酸浆米线";
		setDescription(description);
    }
	
	@Override
	public double cost() {
		return 3;
	}
}
public class NoodlesDry extends Noodles {
	public NoodlesDry() {
		String description="干浆米线";
		setDescription(description);
	}
	
	@Override
	public double cost() {
		return 2;
	}
}
public class NoodlesWater extends Noodles {
	public NoodlesWater() {
    	String description="水米线";
		setDescription(description);
    }
	
	@Override
	public double cost() {
		return 2;
	}
}

Ingredients基类

public abstract class Ingredients extends Noodles {
	public abstract String getDescription();
		
	@Override
	public double cost() {
		return 0;
	}	
}

 Classes inheriting Ingredients

public class Beef extends Ingredients{
	private Noodles noodles=null;
    
	public Beef(Noodles noodles){
		this.noodles = noodles;
	}
	
	@Override
	public String getDescription() {
		String str = noodles.getDescription();
		
		if(str.indexOf("牛肉") != -1){
			return str;
		}else{
			return "牛肉" + noodles.getDescription();
		}
	}
	
	public double cost(){
		return 5 + noodles.cost();
	}
}
public class Egg extends Ingredients {
	private Noodles noodles=null;
    
	public Egg(Noodles noodles){
		this.noodles = noodles;
	}
	
	@Override
	public String getDescription() {
		String str = noodles.getDescription();
		
		if(str.indexOf("鸡蛋") != -1){
			return str;
		}else{
			return "鸡蛋" + noodles.getDescription();
		}
	}
	
	public double cost(){
		return 2 + noodles.cost();
	}
}
public class Tofu extends Ingredients{
	private Noodles noodles=null;
    
	public Tofu(Noodles noodles){
		this.noodles = noodles;
	}
	
	@Override
	public String getDescription() {
		String str = noodles.getDescription();
		
		if(str.indexOf("豆腐") != -1){
			return str;
		}else{
			return "豆腐" + noodles.getDescription();
		}
	}
	
	public double cost(){
		return 2.5 + noodles.cost();
	}
}

Test class

public class Test {
	public static void main(String[] args) {
	    Noodles noodles1 = new NoodlesDry();
	    noodles1 = new Egg(noodles1);
	    noodles1 = new Beef(noodles1);
	    System.out.println(noodles1.getDescription() + noodles1.cost());
	    
	    Noodles noodles2 = new NoodlesAcid();
	    noodles2 = new Tofu(noodles2);
	    noodles2 = new Beef(noodles2);
	    System.out.println(noodles2.getDescription() + noodles2.cost());
	}
}

6. Experimental results

 Abstract Factory Pattern

        The abstract factory pattern provides an interface for creating families of related or dependent objects without the need to specify specific classes. On the basis of familiarity with the relevant theoretical knowledge of the abstract factory pattern, use the abstract factory pattern to realize the "computer configuration store" program. 

1. Basic requirements

Use the abstract factory pattern to realize the "computer configuration store" , the requirements are as follows:

  1. The computer is composed of CPU, motherboard, graphics card, memory, hard disk and other accessories. There are two configuration schemes for the current computer configuration.
  2. According to the configuration scheme, specific configuration information can be displayed.
  3. The price can be displayed according to the configuration plan.

2. Experimental content

        1. Design and draw the class diagram of the program;

        2. Use Java language to write code in accordance with the designed class diagram and implement the program;

        3. In addition to the implementation of core pattern-related classes, a test environment is provided. According to the level of difficulty, they are:

                a) Console program, Client hard-coded initialization mode and test environment, and text output of running results;

                b) Console program, Client initializes the test environment, calculates according to user input, and outputs text output of running results;

                c) Design and implement the user UI, the Client initializes the test environment, and outputs the text output of the running result according to the user's input on the UI control;

Three, experimental tips

        1. The structure and components of the abstract factory pattern

  • Abstract Factory: declares the operation interface for creating abstract product objects;
  • ConcreteFactory: realize the operation of creating specific objects;
  • Abstract Product: Declare an interface for a type of product object;
  • ConcreteProduct: Define a product object created by a specific factory;

        2. Abstract factory pattern code hint

        PizzaStore paradigm: The abstract factory allows customers to use abstract interfaces to create a set of related products without knowing what the actual products are. In this way, customers are decoupled from the specific products.

        PizzaIngredientFactory interface

public interface PizzaIngredientFactory {
 
	public Dough createDough();
	public Sauce createSauce();
	public Cheese createCheese();
	public Veggies[] createVeggies();
	public Pepperoni createPepperoni();
	public Clams createClam();
}

        ChicagoPizzaIngredientFactory concrete implementation class

public class ChicagoPizzaIngredientFactory 
	implements PizzaIngredientFactory 
{

	public Dough createDough() {
		return new ThickCrustDough();
	}

	public Sauce createSauce() {
		return new PlumTomatoSauce();
	}

	public Cheese createCheese() {
		return new MozzarellaCheese();
	}

	public Veggies[] createVeggies() {
		Veggies veggies[] = { new BlackOlives(), 
		                      new Spinach(), 
		                      new Eggplant() };
		return veggies;
	}

	public Pepperoni createPepperoni() {
		return new SlicedPepperoni();
	}

	public Clams createClam() {
		return new FrozenClams();
	}
}

        Pizza base class

public abstract class Pizza {
	String name;

	Dough dough;
	Sauce sauce;
	Veggies veggies[];
	Cheese cheese;
	Pepperoni pepperoni;
	Clams clam;

	abstract void prepare();

	void bake() {
		System.out.println("Bake for 25 minutes at 350");
	}

	void cut() {
		System.out.println("Cutting the pizza into diagonal slices");
	}

	void box() {
		System.out.println("Place pizza in official PizzaStore box");
	}

	void setName(String name) {
		this.name = name;
	}

	String getName() {
		return name;
	}

	public String toString() {
		StringBuffer result = new StringBuffer();
		result.append("---- " + name + " ----\n");
		if (dough != null) {
			result.append(dough);
			result.append("\n");
		}
		if (sauce != null) {
			result.append(sauce);
			result.append("\n");
		}
		if (cheese != null) {
			result.append(cheese);
			result.append("\n");
		}
		if (veggies != null) {
			for (int i = 0; i < veggies.length; i++) {
				result.append(veggies[i]);
				if (i < veggies.length-1) {
					result.append(", ");
				}
			}
			result.append("\n");
		}
		if (clam != null) {
			result.append(clam);
			result.append("\n");
		}
		if (pepperoni != null) {
			result.append(pepperoni);
			result.append("\n");
		}
		return result.toString();
	}
}

        Dough interface and implementation

public interface Dough {
	public String toString();
}

public class ThickCrustDough implements Dough {
	public String toString() {
		return "ThickCrust style extra thick crust dough";
	}
}

         PizzaTestDrive test environment

public class PizzaTestDrive {
 
	public static void main(String[] args) {
		PizzaStore nyStore = new NYPizzaStore();
		PizzaStore chicagoStore = new ChicagoPizzaStore();
 
		Pizza pizza = nyStore.orderPizza("cheese");
		System.out.println("Ethan ordered a " + pizza + "\n");
 
		pizza = chicagoStore.orderPizza("cheese");
		System.out.println("Joel ordered a " + pizza + "\n");

		pizza = nyStore.orderPizza("clam");
		System.out.println("Ethan ordered a " + pizza + "\n");
 
		pizza = chicagoStore.orderPizza("clam");
		System.out.println("Joel ordered a " + pizza + "\n");

		pizza = nyStore.orderPizza("pepperoni");
		System.out.println("Ethan ordered a " + pizza + "\n");
 
		pizza = chicagoStore.orderPizza("pepperoni");
		System.out.println("Joel ordered a " + pizza + "\n");

		pizza = nyStore.orderPizza("veggie");
		System.out.println("Ethan ordered a " + pizza + "\n");
 
		pizza = chicagoStore.orderPizza("veggie");
		System.out.println("Joel ordered a " + pizza + "\n");
	}
}

Fourth, the experimental principle

Five, source code

ComputerStore class

public abstract class ComputerStore {
	ComputerFactory computer;
	public abstract ComputerFactory createComputer(String type) ;
}

Inherit the ComputerStore class

public class Computer extends ComputerStore{
	public  ComputerFactory createComputer(String type){
		ComputerFactory computer=null;
		if(type.equals("A")){
			computer=new AFactory();
		}
		else if(type.equals("B")){
			computer=new BFactory();
		}
		
		computer.createCpu();
		computer.createGraphicsCard();
		computer.createHarddisk();
		computer.createMainboard();
		computer.createRam();
		computer.displayPrice();
		return computer;
	}
}

 ComputerFactory interface

public interface ComputerFactory {
	public Cpu createCpu(); 
	public Mainboard createMainboard(); 
	public GraphicsCard createGraphicsCard();
	public Ram createRam();  
	public Harddisk createHarddisk(); 
	public void displayPrice();
}

Class that implements ComputerFactory

public class AFactory implements ComputerFactory{
	public AFactory(){
		System.out.println("\n方案A:");
	}
	
	public Cpu createCpu() {
		return new ACpu();
	}
	
	public Mainboard createMainboard() {
		return new AMainboard();
	}
	
	public GraphicsCard createGraphicsCard() {
		return new AGraphicsCard();
	}
	
	public Ram createRam() {
		return new ARam();
	}
	
	public Harddisk createHarddisk() {
		return new AHarddisk();
	}
	
	public void displayPrice() {
		System.out.println("RMB:4000");
	}	
}
public class BFactory implements ComputerFactory{
	public BFactory(){
		System.out.println("\n方案B:");
	}
	public Cpu createCpu() {
		return new BCpu();
	}
	public Mainboard createMainboard() {
		return new BMainboard();
	}
	public GraphicsCard createGraphicsCard() {
		return new BGraphicsCard();
	}
	public Ram createRam() {
		return new BRam();
	}
	public Harddisk createHarddisk() {
		return new BHarddisk();
	}
	public void displayPrice() {
		System.out.println("RMB:8000");
	}
}

 Cpu interface

public interface Cpu {
	String Cpu=new String();
}

Class that implements CPU

public class ACpu implements Cpu {
	String Cpu = new String();
	
	public ACpu(){
		Cpu="Intel i5";
		System.out.println("Cpu:" + Cpu);
	}
}
public class BCpu implements Cpu {
	String Cpu = new String();
	
	public BCpu(){
		Cpu="Intel i7";
		System.out.println("Cpu:" + Cpu);
	}
}

 GraphicsCard interface

public interface GraphicsCard {
	String GraphicsCard=new String(); 
}

Class that implements GraphicsCard

public class AGraphicsCard implements GraphicsCard{
	String GraphicsCard=new String();
	
	public AGraphicsCard(){
		GraphicsCard="GTX 1050";
		System.out.println("GraphicsCard:"+GraphicsCard);
	}
}
public class BGraphicsCard implements GraphicsCard{
	String GraphicsCard = new String();
	
	public BGraphicsCard(){
		GraphicsCard="GTX 1050Ti";
		System.out.println("GraphicsCard:"+GraphicsCard);
	}
}

 Harddisk interface

public interface Harddisk {
	String Harddisk=new String();
}

Class that implements Harddisk

public class AHarddisk implements Harddisk{
	String Harddisk=new String();
	
	public AHarddisk(){
		Harddisk="HDD 1T";
		System.out.println("Harddisk:"+Harddisk);
	}
}
public class BHarddisk implements Harddisk {
	String Harddisk=new String();
	
	public BHarddisk(){
		Harddisk="SSD 1T";
		System.out.println("Harddisk:"+Harddisk);
	}
}

 Mianboard interface

public interface Mainboard {
	String Mainboard=new String();
}

Inherit the Mianboard class

public class AMainboard implements Mainboard{
	String Mainboard=new String();
	
	public AMainboard(){
		Mainboard="ASUS";
		System.out.println("Mainboard:"+Mainboard);
	}
}
public class BGraphicsCard implements GraphicsCard{
	String GraphicsCard = new String();
	
	public BGraphicsCard(){
		GraphicsCard="GTX 1050Ti";
		System.out.println("GraphicsCard:"+GraphicsCard);
	}
}

 Ram interface

public interface Ram {
	String Ram =new String();
}

Class that implements Ram

public class ARam implements Ram{
	String Ram=new String();
	
	public ARam(){
		Ram="4g";
		System.out.println("Ram:"+Ram);
	}
}
public class BRam implements Ram{
	String Ram=new String();

	public BRam(){
		Ram="8g";
		System.out.println("Ram:"+Ram);
	}
}

Test class

import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		Computer computer=new Computer ();
		Scanner sc = new Scanner(System.in);
		System.out.println("选项选择电脑配置方案 (A or B)");
    	String k = sc.nextLine();
    	sc.close();
    	switch(k){
    	case "A": case "a":
    		computer.createComputer("A");
    		break;
    	case "B": case "b":
    		computer.createComputer("B");
    		break;
    	default:
    		System.out.println("不存在所选择方案");
    		break;
    	}
	}
}

 6. Experimental results

Command pattern

        Command mode encapsulates "requests" into objects so that different requests, queues, or logs can be used to parameterize other objects. Command mode also supports undoable operations. On the basis of familiarity with the theoretical knowledge of command mode, use command mode to realize image processing program.

1. Basic requirements

        To use the command mode to implement the image processing program , the requirements are as follows:

  1. The picture processing program must have 3 pictures.
  2. There are at least 3 operations for each picture.
  3. Realize the menu similar to the remote control, dynamically select the processing of the picture.
  4. There must be an "undo operation", and the undo operation must be able to be undone to the last step.

2. Experimental content

        1. Design and draw the class diagram of the program;

        2. Use Java language to write code in accordance with the designed class diagram and implement the program;

        3. In addition to the implementation of core pattern-related classes, a test environment is provided. According to the level of difficulty, they are:

                a) Console program, Client hard-coded initialization mode and test environment, and text output of running results;

                b) Console program, Client initializes the test environment, calculates according to user input, and outputs text output of running results;

                c) Design and implement the user UI, the Client initializes the test environment, and outputs the text output of the running result according to the user's input on the UI control;

Three, experimental tips

        1. The structure and components of the command mode

  • Command: declare the interface to perform the operation;
  • ConcreteCommand: Bind a receiver object to an action and call the corresponding operation of the receiver;
  • Client (Application): Create a specific command object and set its receiver;
  • Invoker (MenuItem): request command execution request;
  • Receiver (Document, Application): Know how to implement operations related to the execution of a request;

         2. Command mode code prompt

        RemoteControl example: The command object wraps the action and receiver into the object. This object only exposes an execute() method. When this method is called, the receiver will perform these actions.

         RemoteControl class

public class RemoteControl {
	Command[] onCommands;
	Command[] offCommands;
 
	public RemoteControl() {
		onCommands = new Command[7];
		offCommands = new Command[7];
 
		Command noCommand = new NoCommand();
		for (int i = 0; i < 7; i++) {
			onCommands[i] = noCommand;
			offCommands[i] = noCommand;
		}
	}
  
	public void setCommand(int slot, Command onCommand, Command offCommand) {
		onCommands[slot] = onCommand;
		offCommands[slot] = offCommand;
	}
 
	public void onButtonWasPushed(int slot) {
		onCommands[slot].execute();
	}
 
	public void offButtonWasPushed(int slot) {
		offCommands[slot].execute();
	}
  
	public String toString() {
		StringBuffer stringBuff = new StringBuffer();
		stringBuff.append("\n------ Remote Control -------\n");
		for (int i = 0; i < onCommands.length; i++) {
			stringBuff.append("[slot " + i + "] " + onCommands[i].getClass().getName()
				+ "    " + offCommands[i].getClass().getName() + "\n");
		}
		return stringBuff.toString();
	}
}

         Command class

public interface Command {
	public void execute();
}

         Light class

public class Light {
	String location = "";

	public Light(String location) {
		this.location = location;
	}

	public void on() {
		System.out.println(location + " light is on");
	}

	public void off() {
		System.out.println(location + " light is off");
	}
}

         LightOnCommand class

public class LightOnCommand implements Command {
	Light light;

	public LightOnCommand(Light light) {
		this.light = light;
	}

	public void execute() {
		light.on();
	}
}

         Test environment RemoteLoader

public class RemoteLoader {
 
	public static void main(String[] args) {
		RemoteControl remoteControl = new RemoteControl();
 
		Light livingRoomLight = new Light("Living Room");
		Light kitchenLight = new Light("Kitchen");
		CeilingFan ceilingFan= new CeilingFan("Living Room");
		GarageDoor garageDoor = new GarageDoor("");
		Stereo stereo = new Stereo("Living Room");
  
		LightOnCommand livingRoomLightOn = 
				new LightOnCommand(livingRoomLight);
		LightOffCommand livingRoomLightOff = 
				new LightOffCommand(livingRoomLight);
		LightOnCommand kitchenLightOn = 
				new LightOnCommand(kitchenLight);
		LightOffCommand kitchenLightOff = 
				new LightOffCommand(kitchenLight);
  
		CeilingFanOnCommand ceilingFanOn = 
				new CeilingFanOnCommand(ceilingFan);
		CeilingFanOffCommand ceilingFanOff = 
				new CeilingFanOffCommand(ceilingFan);
 
		GarageDoorUpCommand garageDoorUp =
				new GarageDoorUpCommand(garageDoor);
		GarageDoorDownCommand garageDoorDown =
				new GarageDoorDownCommand(garageDoor);
 
		StereoOnWithCDCommand stereoOnWithCD =
				new StereoOnWithCDCommand(stereo);
		StereoOffCommand  stereoOff =
				new StereoOffCommand(stereo);
 
		remoteControl.setCommand(0, livingRoomLightOn, livingRoomLightOff);
		remoteControl.setCommand(1, kitchenLightOn, kitchenLightOff);
		remoteControl.setCommand(2, ceilingFanOn, ceilingFanOff);
		remoteControl.setCommand(3, stereoOnWithCD, stereoOff);
  
		System.out.println(remoteControl);
 
		remoteControl.onButtonWasPushed(0);
		remoteControl.offButtonWasPushed(0);
		remoteControl.onButtonWasPushed(1);
		remoteControl.offButtonWasPushed(1);
		remoteControl.onButtonWasPushed(2);
		remoteControl.offButtonWasPushed(2);
		remoteControl.onButtonWasPushed(3);
		remoteControl.offButtonWasPushed(3);
	}
}

Fourth, the experimental principle

Five, source code

Picture category

public class Picture1 {
	public String rotate(){
		 return "Picture1旋转";
	}
	
	public String cut(){
		return "Picture1剪切";
	}

	public String mirror(){
		return "Picture1镜像";
	}
}
public class Picture2 {
	public String adjustContrast(){
		return "picture2调节对比度";
	}
	
	public String adjustBrightness(){
		return "picture2调节亮度";
	}
	
	public String adjustSaturation(){
		return "picture2调节饱和度";
	}
}
public class Picture3 {
	public String zoomIn(){
		return "Picture3放大";
	}

	public String zoomOut(){
		return "Picture3缩小";
	}

	public String warping(){
		return "Picture3扭曲";
	}
}

Command interface

public interface Command {
	public String execute();
}

Class that implements Command 

public class CommandCut implements Command {
	Picture1 picture = null;
	
    public CommandCut(Picture1 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.cut();
	}
}
public class CommandMirror implements Command {
	Picture1 picture = null;
	
    public CommandMirror(Picture1 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.mirror();
	}
}
public class CommandRotate implements Command {
	Picture1 picture = null;
	
    public CommandRotate(Picture1 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.rotate();
	}
}
public class CommandWarping implements Command {
	Picture3 picture = null;
	
    public CommandWarping(Picture3 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.warping();
	}
}
public class CommandZoomIn implements Command {
	Picture3 picture = null;
	
    public CommandZoomIn(Picture3 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.zoomIn();
	}
}
public class CommandZoomOut implements Command {
	Picture3 picture = null;
	
    public CommandZoomOut(Picture3 picture){
    	this.picture = picture;
    }
    
	@Override
	public String execute() {
		return picture.zoomOut();
	}
}
public class CommandNo implements Command{
	@Override
	public String execute() {
		return null;
	}
}
public class CommandRevoke implements Command {
	Command command = null;
	
    public CommandRevoke(Command command){
    	this.command = command;
    }
    
	@Override
	public String execute() {
		return "已撤销上一步:" + command.execute();
	}
}

 Test class

public class Test {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		Command command = null;
		while(true) {
			System.out.println("选择要处理的图片:\n1)图片1;2)图片2;3)图片3;0)撤销");
	    	String k = sc.nextLine();
	    	switch(k) {
	    	case "1":
	    		Picture1 picture1 = new Picture1();
	    		System.out.println("选择处理方式:\n1)旋转;2)剪切;3)镜像");
	    		String key1 = sc.nextLine();
	    		switch(key1) {
	    		case "1": command = new CommandRotate(picture1); break;
	    		case "2": command = new CommandCut(picture1); break;
	    		case "3": command = new CommandMirror(picture1); break;
	    		default: command = new CommandNo(); break;
	    		}
	    		break;
	    	case "2":
	    		Picture2 picture2 = new Picture2();
	    		System.out.println("选择处理方式:\n1)调节对比度;2)调节亮度;3)调节饱和度");
	    		String key2 = sc.nextLine();
	    		switch(key2) {
	    		case "1": command = new CommandAdjustContrast(picture2); break;
	    		case "2": command = new CommandAdjustBrightness(picture2); break;
	    		case "3": command = new CommandAdjustSaturation(picture2); break;
	    		default: command = new CommandNo(); break;
	    		}
	    		break;
	    	case "3":
	    		Picture3 picture3 = new Picture3();
	    		System.out.println("选择处理方式:\n1)放大;2)缩小;3)扭曲");
	    		String key3 = sc.nextLine();
	    		switch(key3) {
	    		case "1": command = new CommandZoomIn(picture3); break;
	    		case "2": command = new CommandZoomOut(picture3); break;
	    		case "3": command = new CommandWarping(picture3); break;
	    		default: command = new CommandNo(); break;
	    		}
	    		break;
	    	case "0":
	    		command = new CommandRevoke(command);
	    		break;
	    	}
	    	System.out.println(command.execute());
		}
	}
}

6. Experimental results

Guess you like

Origin blog.csdn.net/qq_41587612/article/details/105313059