Swiftã§æžãå§ãããšããç§ã¯å€ãã®åé¡ã«çŽé¢ããªããã°ãªããŸããã§ãããããã®1ã€ã¯ããã®èšèªã§ã®IoCã³ã³ãããŒéã®ç«¶åããªãããšã§ãã å®éãå°é¢šãšã¹ãŠã£ã³ãžã§ã¯ãã®2ã€ãããªãã Swinjectã«ã¯æ©èœãã»ãšãã©ãªããTyphoonã¯Obj-Cåãã«æžãããŠããŸãããããã¯åé¡ã§ããããããæ±ãããšã¯ç§ã«ãšã£ãŠå€§ããªã¹ãã¬ã¹ã«ãªãããšãå€æããŸããã
ã ãããç¥ãåãã«ãªã-DITranquillity ãSwiftäžã®iOSçšIoCã³ã³ãããŒãã¹ããŒãªãŒããŒããšçµ±åã
ååã«ã€ããŠã®èå³æ·±ã話-äœçŸãã®ç°ãªãã¢ã€ãã¢ã®åŸãç§ã¯ãç©ãããã«èœã¡çããŸããã ååãæãã€ãããšããIoCã³ã³ãããŒãäœæããäž»ãªçç±ã¯Typhoonã§ãããšããäºå®ããå§ããŸããã æåã¯ãå³æžé€šãå°é¢šããã匷ãèªç¶çœå®³ãšåŒã¶ããšã«ã€ããŠèããŠããŸããããå°é¢šã¯ã¹ãã¬ã¹ã§ãããç§ã®å³æžé€šã¯å察ãã€ãŸãå¹³åãæäŸããã¹ãã ãšç§ã¯éã£ãèãæ¹ãããªããã°ãªããªãããšã«æ°ä»ããŸããã
ãã¹ãŠãéçã«ãã§ãã¯ããããšãèšç»ããŸããïŒæ®å¿µãªããããã¹ãŠãå®å šã«å€±æããŸããïŒããŸã
å°é¢šæ奜家ã¯å°ãåæºãããããããŸããããç§ã®æèŠã§ã¯ãäžéšã®ãšã³ãã£ãã£ã®åœåã¯å°é¢šã®åœåãšã¯ç°ãªããŸãã Autofacãšåãã§ãããèšèªã®ç¹æ§ãèæ ®ã«å ¥ããŠããŸãã
ç¹åŸŽ
ã©ã€ãã©ãªã®æ©èœã説æããããšããå§ããŸãã
- ãã®ã©ã€ãã©ãªã¯ãçŽç²ãªSwiftã¯ã©ã¹ã§åäœããŸãã NSObjectããç¶æ¿ããŠãããã³ã«ãObj-CãšããŠå®£èšããå¿ èŠã¯ãããŸããããã®ã©ã€ãã©ãªã䜿çšãããšãçŽç²ãªSwiftã§èšè¿°ã§ããŸãã
- ãã€ãã£ãæ§-äŸåé¢ä¿ã®èšè¿°ã¯ãã€ãã£ãèšèªã§è¡ãããŸããããã«ãããç°¡åãªãªãã¡ã¯ã¿ãªã³ã°ãš...
- ã³ã³ãã€ã«æ®µéã§ã®ã»ãšãã©ã®ãã§ãã¯-Typhoonã®åŸãããã¯æ¥œåã®ããã«èŠãããããããŸãããå€ãã®ã¿ã€ããã¹ãå®è¡æã§ã¯ãªãã³ã³ãã€ã«æ®µéã§æ€åºãããããã§ãã æ®å¿µãªãããã©ã€ãã©ãªã¯å®è¡äžã«ãšã©ãŒãèªæ ¢ããããšã¯ã§ããŸããããåé¡ã®äžéšã¯ç¢ºå®ã«é®æãããŸãã
- ãã¹ãŠã®äŸåæ§æ³šå
¥ãã¿ãŒã³ã®ãµããŒãïŒã€ãã·ã£ã©ã€ã¶ãŒæ³šå
¥ãããããã£æ³šå
¥ãã¡ãœãã泚å
¥ã
ãªããããã¯ãŒã«ãªã®ãããããŸãããã誰ããããã«ã€ããŠæžããŠããŸãã - 埪ç°äŸåé¢ä¿ã®ãµããŒã-ã©ã€ãã©ãªã¯ãããã°ã©ããŒã®ä»å ¥ãªãã«ã埪ç°äŸåé¢ä¿ã®ããŸããŸãªãªãã·ã§ã³ããµããŒãããŸãã
- ã¹ããŒãªãŒããŒããšã®çµ±å-ViewControllersã«çŽæ¥äŸåé¢ä¿ãåã蟌ãããšãã§ããŸãã
ãããŠãŸãïŒ
- ãªããžã§ã¯ãã®åç¶æéã®ãµããŒãã
- 代æ¿ã¿ã€ãã®è¡šç€ºã
- ã¿ã€ããšååã«ããäŸåé¢ä¿ã®è§£æ±ºã
- è€æ°ç»é²;
- åæåãã©ã¡ãŒã¿ãŒã䜿çšããäŸåé¢ä¿ã®è§£æ±ºã
- äŸåé¢ä¿ã解決ããããã®çããšã³ããªã
- ãã¢ãžã¥ãŒã«æ§ãã®ç¹å¥ãªã¡ã«ããºã ã
- CocoaPodsã®ãµããŒãã
- ãã·ã¢èªã®ããã¥ã¡ã³ããŒã·ã§ã³ïŒå®éã«ã¯ãããã¥ã¡ã³ããŒã·ã§ã³ã®ãã©ãããšèšãæ¹ãæ£ç¢ºã§ããå€ãã®ãšã©ãŒããããŸãïŒã
ãããŠããããã¯ãã¹ãŠ1500è¡ã®ã³ãŒãã§ããã®ãã¡çŽ400è¡ã§ãç°ãªãæ°ã®åæåãã©ã¡ãŒã¿ãŒãæã€äŸåé¢ä¿ã®åæå®ããã解決ã®ããã«èªåçã«çæãããã³ãŒãã§ãã
ãããŠãããããã¹ãŠãã©ããããïŒ
ç°¡åã«
ç§ã¯å°ããªæ§æã®äŸããå§ããŸãïŒ
// Classes class TaskRepository: TaskRepositoryProtocol { ... } class LogManager: LoggerProtocol { ... } class TaskController { var logger: LoggerProtocol? = nil private let repository: TaskRepositoryProtocol init(repository:TaskRepository) { self.repository = repository } ... } // Register let builder = DIContainerBuilder() builder.register(TaskRepository.self) .asType(TaskRepositoryProtocol.self) .initializer { TaskRepository() } builder.register(LogManager.self) .asType(LoggerProtocol.self) .initializer { LogManager(Date()) } builder.register(TaskController.self) .initializer { (scope) in TaskController(repository: *!scope) } .dependency { (scope, taskController) in taskController.logger = try? scope.resolve() } let container = try! builder.build() // Resolve let taskController: TaskController = container.resolve()
ãããŠä»ãé çªã«
åºæ¬çãªãããžã§ã¯ãçµ±å
Typhoonãšã¯ç°ãªããã©ã€ãã©ãªã¯plistãŸãã¯åæ§ã®ãæ©èœãããã®ãèªåãåæåããµããŒãããŠããŸããã ååãšããŠãå°é¢šã¯ãã®ãããªæ©äŒããµããŒãããŠãããšããäºå®ã«ãããããããç§ã¯åœŒãã®äŸ¿å®ã«ã€ããŠç¢ºä¿¡ãæãŠãŸããã
å€ããå°ãªããèšç»ãããŠãããããžã§ã¯ããšçµ±åããã«ã¯ã次ã®ãã®ãå¿ èŠã§ãã
- ã©ã€ãã©ãªèªäœããããžã§ã¯ãã«çµ±åããŸãã ããã¯ãCocoapodsã䜿çšããŠå®è¡ã§ããŸãã
pod 'DITranquillity'
- ã©ã€ãã©ãªã䜿çšããŠããŒã¹ã¢ã»ã³ããªã宣èšããŸãïŒãªãã·ã§ã³ïŒïŒ
import DITranquillity class AppAssembly: DIAssembly { // var publicModules: [DIModule] = [ ] var intermalModules: [DIModule] = [ AppModule() ] var dependencies: [DIAssembly] = [ // YourAssembly2(), YourAssembly3() - ] }
- åºæ¬ã¢ãžã¥ãŒã«ã宣èšããŸãïŒãªãã·ã§ã³ïŒïŒ
import DITranquillity class AppModule: DIModule { // func load(builder: DIContainerBuilder) { // // } }
- ã¢ãžã¥ãŒã«ã®ã¿ã€ããç»é²ããŸãïŒäžèšã®æåã®äŸãåç
§ïŒã
- ãã«ããŒã«ããŒã¹ã¢ã»ã³ããªãç»é²ããã³ã³ãããŒãçµã¿ç«ãŠãŸãã
import DITranquillity @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { public func applicationDidFinishLaunching(_ application: UIApplication) { ... let builder = DIContainerBuilder() builder.register(assembly: AppAssembly()) try! builder.build() // // , , , } }
çµµã³ã³ã
ããã€ãã®ã¯ã©ã¹ãäœæããåŸã®æ¬¡ã®ã¹ãããã¯ãStoryboardãäœæãã
class AppModule: DIModule { func load(builder: DIContainerBuilder) { builder.register(UIStoryboard.self) .asName("Main") // .instanceSingle() // .initializer { scope in DIStoryboard(name: "Main", bundle: nil, container: scope) } // } }
AppDelegateãå€æŽããŸãã
public func applicationDidFinishLaunching(_ application: UIApplication) { .... let container = try! builder.build() // window = UIWindow(frame: UIScreen.main.bounds) let storyboard: UIStoryboard = try! container.resolve(Name: "Main") // Main storyboard window!.rootViewController = storyboard.instantiateInitialViewController() window!.makeKeyAndVisible() }
ã¹ããŒãªãŒããŒãäžã®ViewControllers
ãããŠãã³ãŒããå®è¡ãã
ãã¬ãŒã³ã¿ãŒãäœæããŸãã
class YourPresenter { ... }
ãŸããViewControllerã«ååïŒã¿ã€ãïŒãæå®ããããããã£ãŸãã¯ã¡ãœãããä»ããŠã€ã³ãžã§ã¯ã·ã§ã³ãè¿œå ããå¿ èŠããããŸãããã³ãŒãã§ã¯ããããã£ãä»ããã€ã³ãžã§ã¯ã·ã§ã³ã䜿çšããŸãã
class YourViewController: UIViewController { var presenter: YourPresenter! ... }
ãŸããã¹ããŒãªãŒããŒãã§ãViewControllerãUIViewControllerã ãã§ãªãYourViewControllerã§ããããšãå¿ããªãã§ãã ããã
ãããŠãã¢ãžã¥ãŒã«ã«åãç»é²ããå¿ èŠããããŸãã
func load(builder: DIContainerBuilder) { ... builder.register(YourPresenter.self) .instancePerScope() // , scope Presenter .initializer { YourPresenter() } builder.register(YourViewController.self) .instancePerRequest() // ViewController' .dependency { (scope, self) in self.presenter = try! scope.resolve() } // }
ããã°ã©ã ãéå§ãããšãViewControllerã«ãã¬ãŒã³ã¿ãŒãããããšãããããŸãã
ããããã¡ãã£ãšãinstancePerRequestã®å¥åŠãªåç¶æéãšãã€ãã·ã£ã©ã€ã¶ãŒã¯ã©ãã«è¡ããŸãããïŒ Storyboardã«é 眮ãããä»ã®ãã¹ãŠã®ã¿ã€ãã®ViewControllerãšã¯ç°ãªããStoryboardãäœæããã®ã§ã¯ãªããStoryboardãäœæãããããåæååã¯ãªããåæåã¡ãœãããä»ããã€ã³ãžã§ã¯ã·ã§ã³ããµããŒãããŸããã ã€ãã·ã£ã©ã€ã¶ã®ååšã¯ãã³ã³ãããäœæããéã®ãã§ãã¯ãã€ã³ãã®1ã€ã§ããããããã®ã¿ã€ãã¯ç§ãã¡ã§ã¯ãªããä»ã®èª°ãã«ãã£ãŠäœæãããããšã宣èšããå¿ èŠããããŸãã
ããŒã¿ã䜿çšããäœæ¥ãè¿œå ãã
ãã®åŸããããžã§ã¯ãã¯äœããããå¿ èŠããããŸããå€ãã®å Žåãã¢ãã€ã«ããã€ã¹ã«å¯ŸããŠãã¢ããªã±ãŒã·ã§ã³ã¯ãããã¯ãŒã¯ããæ å ±ãåãåããåŠçããŠè¡šç€ºããŸãã ç°¡åã«ããããã«ãããŒã¿åŠçã¹ããããçç¥ãããããã¯ãŒã¯ããããŒã¿ãåä¿¡ãã詳现ã«ã¯è§ŠããŸããã `get`ã¡ãœãããåããServerãããã³ã«ããããããã«å¿ããŠãã®ãããã³ã«ã®å®è£ ããããšä»®å®ããŸãã ã€ãŸãã次ã®ã³ãŒããããã°ã©ã ã«è¡šç€ºãããŸãã
protocol Server { func get(method: String) -> Data? } class ServerImpl: Server { init(domain: String) { ... } func get(method: String) -> Data? { ... } }
ããã§ãæ°ããã¯ã©ã¹ãç»é²ããå¥ã®ã¢ãžã¥ãŒã«ãäœæã§ããŸãã ãã¡ãããããã«å ã«é²ãã§æ°ããã¢ã»ã³ããªãäœæãããµãŒããŒã§ã®äœæ¥ãå¥ã®ãããžã§ã¯ãã«è»¢éããããšãã§ããŸããããã®äŸã¯è€éã«ãªããŸãããã©ã€ãã©ãªã®ããå€ãã®åŽé¢ãšæ©èœã瀺ãããŸãã ãŸãã¯ãéã«ãæ¢åã®ã¢ãžã¥ãŒã«ã«åã蟌ã¿ãŸãã
import DITranquillity class ServerModule: DIModule { func load(builder: DIContainerBuilder) { builder.register(ServerImpl.self) .asSelf() .asType(Server.self) .instanceSingle() .initializer { ServerImpl(domain: "https://your_site.com/") } } }
ServerImplåãç»é²ããŸãããããã°ã©ã ã§ã¯ãServerImplãšServerãšãã2ã€ã®åã§èªèãããŸãã ããã¯ç»é²åäœã®ããã€ãã®æ©èœã§ãã代æ¿ã¿ã€ããæå®ãããŠããå Žåãæ瀺çã«æå®ãããªãéããã¡ã€ã³ã¿ã€ãã¯äœ¿çšãããŸããã ãŸããããã°ã©ã ã«ã¯ãµãŒããŒã1ã€ãããªãããšã瀺ããŸããã
ãŸããã¢ã»ã³ããªãå°ãå€æŽããŠã圌女ãæ°ããã¢ãžã¥ãŒã«ãèªèã§ããããã«ããŸãã
class AppAssembly: DIAssembly { var publicModules: [DIModule] = [ ServerModule() ] }
publicModulesãšinternalModulesã®éã
ã¢ãžã¥ãŒã«ã®å¯èŠæ§ã«ã¯ãå
éšãšãããªãã¯ã®2ã€ã®ã¬ãã«ããããŸãã Public-ãã®ã¢ãžã¥ãŒã«ã衚瀺ãããããšãæå³ãããã®ã¢ã»ã³ããªã䜿çšããä»ã®ã¢ã»ã³ããªã§ã¯ãInternal-ã¢ãžã¥ãŒã«ã¯ã¢ã»ã³ããªå
ã§ã®ã¿è¡šç€ºãããŸãã 確ãã«ãã¢ã»ã³ããªã¯åãªãã¢ããŠã³ã¹ã§ãããããã¢ãžã¥ãŒã«ã®å¯èŠæ§ã«é¢ãããã®èŠåã¯ãååã«åŸã£ãŠã³ã³ãããŒã«é©çšãããããšãæ確ã«ããå¿
èŠããããŸãïŒãã«ããŒã«çŽæ¥è¿œå ãããã¢ã»ã³ããªã®ãã¹ãŠã®ã¢ãžã¥ãŒã«ã¯ã圌ãæ§ç¯ããã³ã³ãããŒãããã³äŸåã¢ã»ã³ããªã®ã¢ãžã¥ãŒã«ã«å«ãŸããŸãã³ã³ããããããªãã¯ãšå®£èšãããŠããå Žåã«ã®ã¿ã³ã³ããã«å«ãŸããŸãã
次ã«ãPresenterãå°ãä¿®æ£ããŸãããããµãŒããŒãå¿ èŠãªæ å ±ã圌ã«è¿œå ããŸãã
class YourPresenter { private let server: Server init(server: Server) { self.server = server } }
åæåã¡ãœããã䜿çšããŠäŸåé¢ä¿ãå®è£ ããŸããããViewControllerã®å Žåã®ããã«ãããããã£ãŸãã¯ã¡ãœããã䜿çšããŠå®è£ ã§ããŸãã
ãããŠããã¬ãŒã³ã¿ãŒã®ç»é²ãå®äºããŠããŸã-ãã¬ãŒã³ã¿ãŒã«ãµãŒããŒãå®è£ ãããšèšããŸãã
builder.register(YourPresenter.self) .instancePerScope() // , scope Presenter .initializer { (scope) in YourPresenter(server: *!scope) }
ããã§ã¯ããé«éãæ§æ `*ïŒ`ã䜿çšããŠãäŸåé¢ä¿ãååŸããŸãããããã¯ãè¡šèšæ³ãšåçã§ãïŒ `tryïŒ scope.resolveïŒïŒ `
ããã°ã©ã ãèµ·åãããã¬ãŒã³ã¿ãŒã«ãµãŒããŒãããããšã確èªããŸãã ããã§äœ¿çšã§ããŸãã
ãã¬ãŒãå®è£ ããŸã
ç§ãã¡ã®ããã°ã©ã ã¯åäœããŸãããäžéšã®ãŠãŒã¶ãŒã«ãšã£ãŠã¯ãçªç¶æ£ããåäœããªããªããŸããã èªå® ã§åé¡ãåçŸããŠå€æããããšã¯ã§ããŸãã-ããã¯ãã€ã§ãããã¬ãŒãå¿ èŠã§ãã ããããè¶ åžžçŸè±¡ã«å¯Ÿããç§ãã¡ã®ä¿¡å¿µã¯æ¢ã«èŠéããŠããã®ã§ããã¬ãŒã¯ãã¡ã€ã«ãã³ã³ãœãŒã«ããµãŒããŒãããã«ã¯æµ·ã®å Žæã«ããŒã¿ãæžã蟌ãå¿ èŠããããããããã¹ãŠãç°¡åã«ãªã³/ãªãããŠäœ¿çšããå¿ èŠããããŸãã
ãã®ãããé¢æ°logïŒã¡ãã»ãŒãžïŒæååïŒã䜿çšããŠåºæ¬ãããã³ã« `Logger`ãäœæããããã€ãã®å®è£ ãå®è£ ããŸããConsoleLoggerãFileLoggerãServerLogger ...ãã®ä»ãã¹ãŠããã«ããåºæ¬ãã¬ãŒãäœæããMainLoggerãšåŒã³ãŸãã ããã«ããã°ãèšé²ããã¯ã©ã¹ã§ã¯ãé¡äŒŒæ§ã«é¢ããè¡ãè¿œå ããŸãïŒ `var logïŒLoggerïŒ = nil`ãããã³...ãããŠãå®è¡ãããã¹ãŠã®ã¢ã¯ã·ã§ã³ãç»é²ããå¿ èŠããããŸãã
æåã«ãæ°ããLoggerModuleã¢ãžã¥ãŒã«ãäœæããŸãã
import DITranquillity class LoggerModule: DIModule { func load(builder: DIContainerBuilder) { builder.register(ConsoleLogger.self) .asType(Logger.self) .instanceSingle() .initializer { ConsoleLogger() } builder.register(FileLogger.self) .asType(Logger.self) .instanceSingle() .initializer { FileLogger(file: "file.log") } builder.register(ServerLogger.self) .asType(Logger.self) .instanceSingle() .initializer { ServerLogger(server: "http://server.com/") } builder.register(MainLogger.self) .asType(Logger.self) .asDefault() .instanceSingle() .initializer { scope in MainLogger(loggers: **!scope) } } }
ãããŠãããšãã°æ¬¡ã®ããã«ããã¬ãŒã®å°å ¥ã宣èšãããã¹ãŠã®ã¯ã©ã¹ã«è¿œå ããããšãå¿ããªãã§ãã ããã
builder.register(YourPresenter.self) .instancePerScope() // , scope Presenter .initializer { scope in try YourPresenter(server: *!scope) } .dependency { (scope, obj) in obj.log = *?scope }
ãããŠããããã¢ã»ã³ããªã«è¿œå ããŸãã ä»ãç§ãã¡ãæžããã°ããã®ãã®ãäœã䟡å€ããããŸãã
æåã«ã3ã€ã®ãã¬ãŒãç»é²ããŸãããããã¯ããã¬ãŒãšããååã§å©çšã§ããŸããã€ãŸããè€æ°ã®ç»é²ãå®è¡ããŸããã ããã«ãMainLoggerãåé€ãããšãããã°ã©ã ã¯1ã€ã®ãã¬ãŒãæããªããªããŸãã1ã€ã®ãã¬ãŒãååŸãããå Žåãã©ã€ãã©ãªã¯ããã°ã©ããã©ã®ãã¬ãŒãæãã§ããããç解ã§ããªãããã§ãã 次ã«ãMainLoggerã«å¯ŸããŠ2ã€ã®ããšãè¡ããŸãã
- ããã¯æšæºã®ãã¬ãŒã ãšèšããŸãã ã€ãŸããåäžã®ãã¬ãŒãå¿
èŠãªå Žåãããã¯MainLoggerã§ãããä»ã®ãã¬ãŒã§ã¯ãããŸããã
- MainLoggerã§ã¯ãèªåèªèº«ãé€ããã¹ãŠã®ãã¬ãŒã®ãªã¹ãã転éããŸãïŒããã¯ã©ã€ãã©ãªã®æ©èœã®1ã€ã§ãããè€æ°ã®äŸåé¢ä¿ã解決ã§ãããããååž°åŒã³åºãã¯é€å€ãããŸããããã¯ããtryïŒãã«çžåœããé«éæ§æã**ïŒãã䜿çšããŸãã scope.resolveManyïŒïŒ `
ãŸãšã
ã©ã€ãã©ãªã䜿çšããŠãã«ãŒã¿ãŒãViewControllerããã¬ãŒã³ã¿ãŒãããŒã¿ãªã©ã®è€æ°ã®ã¬ã€ã€ãŒéã®äŸåé¢ä¿ãæ§ç¯ããããšãã§ããŸããã ããããã£ãä»ããŠäŸåé¢ä¿ãæ³šå ¥ãããåæååã代æ¿ã¿ã€ããã¢ãžã¥ãŒã«ãä»ããŠäŸåé¢ä¿ãæ³šå ¥ãããã©ã€ãã¿ã€ã ãšã¢ã»ã³ããªã«ãããã«è§Šãããªã©ã®ããšã瀺ãããŸããã
å€ãã®æ©äŒã倱ãããŸããïŒåšæçãªäŸåé¢ä¿ãååãã©ã€ãã¿ã€ã ãã¢ã»ã³ããªã«ããäŸåé¢ä¿ã®ååŸã ãããã¯ããã¥ã¡ã³ãã§èŠãããšãã§ããŸãã
ãã®äŸã¯ã ãã®ãªã³ã¯ããå ¥æã§ããŸãã
èšç»
- 詳现ãªãã°ãè¿œå ãããã°ãéä¿¡ãããå€éšæ©èœãæå®ããæ©èœ
- ä»ã®ã·ã¹ãã ã®ãµããŒãïŒMacOSãWatchOSïŒ
代æ¿æ¡
- å°é¢š -çŽç²ãªè¿ éåããµããŒãããŠãããããã®æ§æã¯ç§ã®æèŠã§ã¯é¢åã§ã
- Swinject-代æ¿ã¿ã€ãã®æ¬ åŠãããã³è€æ°ã®ç»é²ã ãã¢ãžã¥ãŒã«æ§ãã®ã¡ã«ããºã ã¯ããŸãéçºãããŠããŸããããããã¯åªãã代æ¿æ段ã§ã
PS
çŸæç¹ã§ã¯ããããžã§ã¯ãã¯ãã¬ãªãªãŒã¹ç¶æ
ã«ãããŸããããŒãžã§ã³1.0.0ãæäŸããåã«ãä»ã®äººã®æèŠãç¥ããããšæããŸãããå
¬åŒããªãªãŒã¹åŸã«äœããå€æŽããã®ãã¯ããã«é£ãããªãããã§ãã