开闭原则

main
陈彤 4 months ago
parent 2fa585b5f8
commit 428755ed89

@ -0,0 +1,80 @@
package challenge;
import basic.Shape;
import advanced.Resizable;
/**
* ShapeResizable
*/
public class Circle implements Shape, Resizable {
private String color;
private double radius;
/**
*
* @param color
* @param radius
*/
public Circle(String color, double radius) {
this.color = color;
this.radius = radius;
}
@Override
public String getColor() {
return color;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void display() {
System.out.println("Circle [color=" + color + ", radius=" + radius + ", area=" + getArea() + "]");
}
@Override
public void enlarge(double factor) {
if (factor > 0) {
this.radius *= factor;
}
}
@Override
public void shrink(double factor) {
if (factor > 0 && factor < 1) {
this.radius *= factor;
}
}
@Override
public String getSizeInfo() {
return "Circle with radius: " + radius + ", area: " + getArea();
}
/**
*
* @return
*/
public double getRadius() {
return radius;
}
/**
*
* @param radius
*/
public void setRadius(double radius) {
this.radius = radius;
}
/**
*
* @param color
*/
public void setColor(String color) {
this.color = color;
}
}

@ -0,0 +1,60 @@
package challenge;
import basic.Shape;
/**
* ShapeConverter
*/
public class CircleToEllipseConverter implements ShapeConverter {
private double stretchFactor; // 拉伸因子,用于确定椭圆的长半轴
/**
*
* @param stretchFactor 1
*/
public CircleToEllipseConverter(double stretchFactor) {
this.stretchFactor = Math.max(stretchFactor, 1.0); // 确保拉伸因子至少为1
}
@Override
public Shape convert(Shape sourceShape) {
if (!canConvert(sourceShape)) {
return null;
}
Circle circle = (Circle) sourceShape;
double radius = circle.getRadius();
// 将圆形转换为椭圆形:保持颜色不变,半径作为短半轴,拉伸后的半径作为长半轴
double semiMinorAxis = radius;
double semiMajorAxis = radius * stretchFactor;
return new Ellipse(circle.getColor(), semiMajorAxis, semiMinorAxis);
}
@Override
public boolean canConvert(Shape sourceShape) {
return sourceShape instanceof Circle;
}
@Override
public String getConversionDescription() {
return "将圆形转换为椭圆形,拉伸因子为:" + stretchFactor;
}
/**
*
* @return
*/
public double getStretchFactor() {
return stretchFactor;
}
/**
*
* @param stretchFactor
*/
public void setStretchFactor(double stretchFactor) {
this.stretchFactor = Math.max(stretchFactor, 1.0);
}
}

@ -0,0 +1,143 @@
package challenge;
import basic.Shape;
import advanced.Resizable;
import java.util.ArrayList;
import java.util.List;
/**
* ShapeResizable
*/
public class CompositeShape implements Shape, Resizable {
private String color;
private String name;
private List<Shape> shapes;
/**
*
* @param name
* @param color
*/
public CompositeShape(String name, String color) {
this.name = name;
this.color = color;
this.shapes = new ArrayList<>();
}
/**
*
* @param shape
*/
public void addShape(Shape shape) {
if (shape != null) {
shapes.add(shape);
}
}
/**
*
* @param shape
* @return truefalse
*/
public boolean removeShape(Shape shape) {
return shapes.remove(shape);
}
/**
*
*/
public void clearShapes() {
shapes.clear();
}
/**
*
* @return
*/
public List<Shape> getShapes() {
return new ArrayList<>(shapes); // 返回副本,防止外部修改
}
@Override
public String getColor() {
return color;
}
@Override
public double getArea() {
double totalArea = 0.0;
for (Shape shape : shapes) {
totalArea += shape.getArea();
}
return totalArea;
}
@Override
public void display() {
System.out.println("CompositeShape [name=" + name + ", color=" + color + ", totalShapes=" + shapes.size() + ", totalArea=" + getArea() + "]");
System.out.println(" 子图形列表:");
for (int i = 0; i < shapes.size(); i++) {
System.out.print(" " + (i + 1) + ". ");
shapes.get(i).display();
}
}
@Override
public void enlarge(double factor) {
if (factor > 0) {
for (Shape shape : shapes) {
if (shape instanceof Resizable) {
((Resizable) shape).enlarge(factor);
}
}
}
}
@Override
public void shrink(double factor) {
if (factor > 0 && factor < 1) {
for (Shape shape : shapes) {
if (shape instanceof Resizable) {
((Resizable) shape).shrink(factor);
}
}
}
}
@Override
public String getSizeInfo() {
return "CompositeShape '" + name + "' with " + shapes.size() + " shapes, total area: " + getArea();
}
/**
*
* @return
*/
public String getName() {
return name;
}
/**
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* @param color
*/
public void setColor(String color) {
this.color = color;
}
/**
*
* @return
*/
public int getShapeCount() {
return shapes.size();
}
}

@ -0,0 +1,101 @@
package challenge;
import basic.Shape;
import advanced.Resizable;
/**
* ShapeResizable
*/
public class Ellipse implements Shape, Resizable {
private String color;
private double semiMajorAxis; // 长半轴
private double semiMinorAxis; // 短半轴
/**
*
* @param color
* @param semiMajorAxis
* @param semiMinorAxis
*/
public Ellipse(String color, double semiMajorAxis, double semiMinorAxis) {
this.color = color;
this.semiMajorAxis = Math.max(semiMajorAxis, semiMinorAxis); // 确保长半轴不小于短半轴
this.semiMinorAxis = Math.min(semiMajorAxis, semiMinorAxis);
}
@Override
public String getColor() {
return color;
}
@Override
public double getArea() {
return Math.PI * semiMajorAxis * semiMinorAxis;
}
@Override
public void display() {
System.out.println("Ellipse [color=" + color + ", semiMajorAxis=" + semiMajorAxis + ", semiMinorAxis=" + semiMinorAxis + ", area=" + getArea() + "]");
}
@Override
public void enlarge(double factor) {
if (factor > 0) {
this.semiMajorAxis *= factor;
this.semiMinorAxis *= factor;
}
}
@Override
public void shrink(double factor) {
if (factor > 0 && factor < 1) {
this.semiMajorAxis *= factor;
this.semiMinorAxis *= factor;
}
}
@Override
public String getSizeInfo() {
return "Ellipse with semi-major axis: " + semiMajorAxis + ", semi-minor axis: " + semiMinorAxis + ", area: " + getArea();
}
/**
*
* @return
*/
public double getSemiMajorAxis() {
return semiMajorAxis;
}
/**
*
* @param semiMajorAxis
*/
public void setSemiMajorAxis(double semiMajorAxis) {
this.semiMajorAxis = semiMajorAxis;
}
/**
*
* @return
*/
public double getSemiMinorAxis() {
return semiMinorAxis;
}
/**
*
* @param semiMinorAxis
*/
public void setSemiMinorAxis(double semiMinorAxis) {
this.semiMinorAxis = semiMinorAxis;
}
/**
*
* @param color
*/
public void setColor(String color) {
this.color = color;
}
}

@ -0,0 +1,109 @@
package challenge;
import basic.Shape;
import java.util.ArrayList;
import java.util.List;
/**
*
*/
public class ShapeConversionSystem {
private List<ShapeConverter> converters;
/**
*
*/
public ShapeConversionSystem() {
this.converters = new ArrayList<>();
}
/**
*
* @param converter
*/
public void addConverter(ShapeConverter converter) {
if (converter != null && !converters.contains(converter)) {
converters.add(converter);
}
}
/**
*
* @param converter
* @return truefalse
*/
public boolean removeConverter(ShapeConverter converter) {
return converters.remove(converter);
}
/**
*
* @param sourceShape
* @return
*/
public List<ShapeConverter> findSuitableConverters(Shape sourceShape) {
List<ShapeConverter> suitableConverters = new ArrayList<>();
for (ShapeConverter converter : converters) {
if (converter.canConvert(sourceShape)) {
suitableConverters.add(converter);
}
}
return suitableConverters;
}
/**
* 使
* @param converter 使
* @param sourceShape
* @return null
*/
public Shape convert(ShapeConverter converter, Shape sourceShape) {
if (converter != null && converter.canConvert(sourceShape)) {
return converter.convert(sourceShape);
}
return null;
}
/**
* 使
* @param sourceShape
* @return null
*/
public Shape convert(Shape sourceShape) {
List<ShapeConverter> suitableConverters = findSuitableConverters(sourceShape);
if (!suitableConverters.isEmpty()) {
return suitableConverters.get(0).convert(sourceShape);
}
return null;
}
/**
*
* @return
*/
public List<ShapeConverter> getAllConverters() {
return new ArrayList<>(converters);
}
/**
*
*/
public void displayAvailableConverters() {
System.out.println("===== 可用的图形转换器 =====");
if (converters.isEmpty()) {
System.out.println("暂无可用的转换器");
} else {
for (int i = 0; i < converters.size(); i++) {
System.out.println((i + 1) + ". " + converters.get(i).getConversionDescription());
}
}
System.out.println("=============================");
}
/**
*
*/
public void clearConverters() {
converters.clear();
}
}

@ -0,0 +1,28 @@
package challenge;
import basic.Shape;
/**
*
*/
public interface ShapeConverter {
/**
*
* @param sourceShape
* @return null
*/
Shape convert(Shape sourceShape);
/**
*
* @param sourceShape
* @return truefalse
*/
boolean canConvert(Shape sourceShape);
/**
*
* @return
*/
String getConversionDescription();
}
Loading…
Cancel
Save