Software Design Patterns and Architecture [Experimental Report Collection]

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

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

Strategy Pattern

       The strategy pattern defines a family of algorithms and encapsulates them separately so that they can be replaced with each other. This pattern allows the changes of the algorithm to be independent of the clients using the algorithm. On the basis of being familiar with the theoretical knowledge related to 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 woman, ninja;
  2. Each character has health and mana, but each character is different.
  3. Each character looks different.
  4. Each character has magic attack and physical attack;
  5. There are three types of physical attacks: with a knife, with a sword, and with the 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 reference https://blog.csdn.net/qq_42685588/article/details/103576562

2. Experimental content

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

       2. Write code in Java language according to the designed class diagram, and implement the program;

       3. In addition to the core mode-related class implementations, test environments are provided, which are:

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

              b) Console program, Client initializes the test environment, performs operations 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 runs the result text output according to the user's input operation on the UI control;

3. Experimental Tips

       1. Structure and Components of the Strategy Pattern

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

       2. Strategy pattern code hints [ from the book "Head First Design Patterns" ]

       SimUDuck Paradigm: Understand the duck's behavior as "a set of behaviors" and implement it using a "family of algorithms" of the strategy pattern.

        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 interfaces

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 graph)

                                                                               Figure 1 Strategy pattern class diagram 

5. 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 (subclass)

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() ;
}

A 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() ;
}

A class that implements 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();
	}
}

 6. Operation results

 Decorator Pattern

        The decorator pattern dynamically attaches responsibilities to objects, providing a more flexible alternative to inheritance for extending functionality. On the basis of being familiar with the relevant theoretical knowledge of the decorator pattern, use the decorator pattern to realize the checkout applet of the rice noodle shop.

1. Basic requirements

        Use the decorator pattern to implement the checkout procedure of the rice noodle shop , the requirements are as follows:

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

2. Experimental content

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

        2. Write code in Java language according to the designed class diagram, and implement the program;

        3. In addition to the core mode-related class implementations, test environments are provided, which are:

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

              b) Console program, Client initializes the test environment, performs operations 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 runs the result text output according to the user's input operation on the UI control;

3. Experimental Tips

        1. The structure and components of the decorator pattern

  • Component: object interface, which can dynamically add responsibilities to objects;
  • Concrete Component: concrete object;
  • Decorator: maintains a pointer to the Component object and defines an interface consistent with the Component interface;
  • ConcreteDecorator: Add responsibilities to components;
  • Decorator forwards the request to its Component object, and may perform some additional actions before and after forwarding the request;

        2. Decorator pattern code hints

        Starbuzz paradigm: drink as the main body, and then "decorate" the drink with spices at runtime.

        Beverage base class

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

        HouseBlend specific beverage category

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

        CondimentDecorator Condiment base class

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

        Soy specific seasoning

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 graph)

 5. 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();
}

 A class that inherits Noodles

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 that inherit 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 explicitly specifying a concrete class. On the basis of being familiar with the relevant theoretical knowledge of the abstract factory pattern, the "computer configuration store" program is realized by using the abstract factory pattern. 

1. Basic requirements

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

  1. A 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. Specific configuration information can be displayed according to the configuration scheme.
  3. Prices can be displayed according to the configuration scheme.

2. Experimental content

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

        2. Write code in Java language according to the designed class diagram, and implement the program;

        3. In addition to the core mode-related class implementations, test environments are provided, which are:

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

                b) Console program, Client initializes the test environment, performs operations 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 runs the result text output according to the user's input operation on the UI control;

3. Experimental Tips

        1. The structure and components of the abstract factory pattern

  • Abstract Factory: declares the operation interface for creating abstract product objects;
  • ConcreteFactory: realizes the operation of creating concrete objects;
  • Abstract Product: declares an interface for a class of product objects;
  • ConcreteProduct: defines a product object created by a concrete factory;

        2. Abstract Factory Pattern Code Hints

        PizzaStore Paradigm: An abstract factory allows a client to use an abstract interface to create a set of related products without needing to know what the actual product is, so the client is decoupled from the concrete product.

        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");
	}
}

4. Experimental principle

5. Source code

ComputerStore class

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

A class that inherits ComputerStore

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();
}

A 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();
}

A 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(); 
}

A 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();
}

A 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();
}

A class that inherits Mianboard

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();
}

A 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

        The command pattern encapsulates "requests" into objects so that other objects can be parameterized with different requests, queues, or logs. The command pattern also supports undoable operations. On the basis of being familiar with the theoretical knowledge of command mode, use command mode to realize image processing program.

1. Basic requirements

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

  1. The image processing program has 3 images.
  2. There are at least 3 operations per image.
  3. Realize a menu similar to the remote control, and dynamically select the processing of the picture.
  4. To have an "undo operation", the undo operation must be undoable to the last step.

2. Experimental content

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

        2. Write code in Java language according to the designed class diagram, and implement the program;

        3. In addition to the core mode-related class implementations, test environments are provided, which are:

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

                b) Console program, Client initializes the test environment, performs operations 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 runs the result text output according to the user's input operation on the UI control;

3. Experimental Tips

        1. The structure and components of the command pattern

  • Command: declares the interface to perform the operation;
  • ConcreteCommand: Bind a receiver object to an action and call the receiver's corresponding operation;
  • Client (Application): Create a specific command object and set its receiver;
  • Invoker (MenuItem): asks the command to execute the request;
  • Receiver(Document, Application): Knows how to implement operations related to executing a request;

         2. Command mode code prompt

        RemoteControl example: Command objects wrap actions and receivers into objects. This object only exposes an execute() method, and 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);
	}
}

4. Experimental principle

5. Source code

pictures

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();
}

A 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 http://43.154.161.224:23101/article/api/json?id=324267160&siteId=291194637